Cách xây dựng directive bằng Angular Js 1

Khi tạo 1 directive, đầu tiên ta phải suy nghĩ xem ta viết cái gì? Sau đó ta xem directive của ta hoạt động ra sao? Và cuối cùng là ta truyền vào cái gì để nó hoạt động?

Để mô tả luồng tư duy, mình thử viết 1 modal directive cơ bản nhất:
– Viết cái gì: Modal
– Hoạt động: Modal có tính năng click vào button thì hiện lên, click vào background thì tắt đi.
– Truyền vào: Biến bật/tắt và Content của modal.

Sau khi tư duy xong, ta có thể khái quát được mô hình như sau:
– name directive: modalWindow
– replace: true (dĩ nhiên)
– transclude: true (vì cần truyền content vào modal, sau này cứ khi nào directive cần truyền dynamic content vào thì transclude là true hết)
– biến bật/tắt: show (false là tắt, true là bật) Continue reading Cách xây dựng directive bằng Angular Js 1

Advertisements

Angular Js 1: Auth check when change state

Controller:

...
$stateProvider
  .state('home.contact', {
    url: '/contact',
    resolve: {
      currentAuth: function(AuthFactory) {
        return AuthFactory.authPromise();
      }
    }
  });
...

Service:

...
.factory('AuthFactory', function ($q, $timeout, $rootScope) {
  var factoryObject = {
    authPromise: function () { /* promise to check is login or not */
      // Initialize a new promise
      var deferred = $q.defer();
      $timeout(function () {
        if ($rootScope.isAuthenticated) {
          deferred.resolve();
        } else {
          deferred.reject('AUTH_REQUIRED');
        }
      });
      return deferred.promise;
    }
  };
  return factoryObject;
})
...

Root Controller:

...
$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
  if (error === 'AUTH_REQUIRED') {
    $state.go('home.dash');
  }
});
...

Use promise in Angular Js 1

// Story: One morning, a father says to his son: "Go and get the weather forecast, son!"
// Every Sunday morning, a father asks his son to go and find out the weather forecast for the afternoon, by using his super-strong telescope to look across the horizon from the tallest hill by their house. The son promises his dad he will go and get the weather forecast. He creates a promise with his dad at the door when he leaves.
// At that point, the dad decides if the weather tomorrow is good, he'll prepare a fishing trip for tomorrow. If it's bad he won't. Also, if the son is unable to get a forecast, he'll stay in as well.
// After 30mins or so, the son comes back. Different things happen from week-to-week
// ---------------------------------------------------------------------------
// can detect the result
var prepareFishingTrip = function (data) {
    console.log('the weather is fine');
    console.log(data);
};
var prepareSundayRoastDinner = function prepareSundayRoastDinner (data) {
    console.log('the weather is bad');
    console.log(data);
};
// can't detect the result
var dontKnowPrepareSundayRoastDinnerOrNot = function prepareSundayRoastDinner (res) {
    console.log('the son can\'t retrieve the weather, he return everything');
    console.log(res);
};
angular.module('myApp', [])
.factory('SonService', function ($http, $q) {
    return {
        getWeather: function() {
            // the $http API is based on the deferred/promise APIs exposed by the $q service
            // so it returns a promise for us by default
            return $http.get('http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=2de143494c0b295cca9337e1e96b00e0')
                .success(function(res) {
                    if (typeof res.data === 'object') {
                        return res.data;
                    } else {
                        // invalid response
                        return $q.reject(res);
                    }
                })
                .error(function(res) {
                    // something went wrong
                    return $q.reject(res);
                });
        }
    };
})
.controller('Ctrl', function($q, SonService) {
    SonService.getWeather()
        // success() called when son gets back
        .success(function(data) {
            // promise fulfilled
            if (data.wind && data.wind.speed > 2) { // if success
                prepareFishingTrip(data);
            } else {
                prepareSundayRoastDinner(data); // if the weather is not good
            }
        })
        .error(function(res) {
            // promise rejected
            dontKnowPrepareSundayRoastDinnerOrNot(res);
        });
});

Apache/Nginx/Xampp apache enable CORS Access-Control-Allow-Origin for Angular Js

More information, you should check here: https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
How CORS works:
1
The browser sends the OPTIONS request with an Origin HTTP header. The value of this header is the domain that served the parent page. When a page from http://www.foo.com attempts to access a user’s data in bar.com, the following request header would be sent to bar.com:

Origin: http://www.foo.com

The server may respond with:
An Access-Control-Allow-Origin (ACAO) header in its response indicating which origin sites are allowed. For example:

Access-Control-Allow-Origin: http://www.foo.com

Preflight example
When performing certain types of cross-domain AJAX requests, modern browsers that support CORS will insert an extra “preflight” request to determine whether they have permission to perform the action.

OPTIONS /
Host: bar.com
Origin: http://foo.com

If bar.com is willing to accept the action, it may respond with the following headers:

Access-Control-Allow-Origin: http://foo.com
Access-Control-Allow-Methods: PUT, DELETE

Continue reading Apache/Nginx/Xampp apache enable CORS Access-Control-Allow-Origin for Angular Js

Set up browser-sync with Gulp

var gulp = require('gulp'),
    browserSync  = require('browser-sync').create(),
    gulpif       = require('gulp-if'),
    gutil        = require('gulp-util'),
    uglify       = require('gulp-uglify'),
    concat       = require('gulp-concat'),
    cssmin       = require('gulp-cssmin'),
    sass         = require('gulp-sass'),
    sourcemaps   = require('gulp-sourcemaps'),
    plumber      = require('gulp-plumber');
var errorHandle = function (error) {
    gutil.log(gutil.colors.red(error.message));
    this.emit('end');
};
var production = false;
/**
 * Copy any needed files
 * Do a 'gulp copyfiles' after bower updates
 **/
gulp.task("copyfiles", function() {
    ...
});
var paths = {};
paths.scripts_1 = [
    ...
];
paths.scripts_2 = [
    ...
];
paths.scripts_3 = [
    ...
];
paths.css_1 = [
    ...
];
paths.css_2 = [
    ...
];
gulp.task('buildVendorJs', function() {
  return gulp.src(paths.scripts_1)
      .pipe(plumber(errorHandle)) /* replaces pipe method and removes standard onerror handler on error event */
      .pipe(sourcemaps.init())
      .pipe(concat('vendors.js'))
      .pipe(gulpif(production, uglify({ mangle: false })))
      .pipe(sourcemaps.write('./'))
      .pipe(gulp.dest('./public/assets/js'));
});
gulp.task('buildAppJs', function() {
  return ...;
});
gulp.task('buildLangJs', function() {
  return ...;
});
gulp.task('buildVendorCss', function() {
  return gulp.src(paths.css_1)
      .pipe(plumber(errorHandle)) /* replaces pipe method and removes standard onerror handler on error event */
      .pipe(sourcemaps.init())
      .pipe(concat('vendors.css'))
      .pipe(sass())
      .pipe(gulpif(production, cssmin()))
      .pipe(sourcemaps.write('./'))
      .pipe(gulp.dest('./public/assets/css'));
});
gulp.task('buildAppCss', function() {
  return ...;
});
gulp.task('default', ['buildVendorJs', 'buildAppJs', 'buildLangJs', 'buildVendorCss', 'buildAppCss'], function () {
  browserSync.init({
      proxy:      'my.app'
  });
  gulp.watch(paths.scripts_1, ['buildVendorJs', browserSync.reload]);
  gulp.watch(paths.scripts_2, ['buildAppJs', browserSync.reload]);
  gulp.watch(paths.scripts_3, ['buildLangJs', browserSync.reload]);
  gulp.watch(paths.css_1, ['buildVendorCss', browserSync.reload]);
  gulp.watch(paths.css_2, ['buildAppCss', browserSync.reload]);
  gulp.watch([
    'app/Http/**/*',
    'app/Library/**/*',
    'app/Models/**/*',
    'app/*',
    'resources/views/**/*'
  ], browserSync.reload);
});

Group Date, Month with Javascript Reduce

var data = [{
  date: '2015-10-30',
  title: 'jerry'
}, {
  date: '2015-10-30',
  title: 'tom'
}, {
  date: '2015-10-31',
  title: 'tom'
}, {
  date: '2015-10-31',
  title: 'tom'
}, {
  date: '2015-11-01',
  title: 'tom'
}, {
  date: '2015-11-01',
  title: 'tom'
}, {
  date: '2015-11-02',
  title: 'tom'
}, {
  date: '2015-11-02',
  title: 'tom'
}, {
  date: '2015-11-03',
  title: 'tom'
}, {
  date: '2015-11-03',
  title: 'tom'
}];

var groupsLevel1 = _.reduce(data, groupByDate, {});
var groupsLevel2 = _.reduce(groupsLevel1, groupByMonth, {});

console.log(groupsLevel2);

function groupByDate(groups, item) {
  var date = item.date;
  var group;

  if (!(date in groups)) {
    group = groups[date] = [];
  } else {
    group = groups[date];
  }

  group.push(item);
  
  return groups;
}

function groupByMonth (groups, item) {
  var date = item[0].date,
      month = date.substr(0, 7),
      group;
  if (!(month in groups)) {
    group = groups[month] = {};
  } else {
    group = groups[month];
  }
  group[date] = item;
  return groups;
}

Using Yield in PHP to generate the combobox values

Generators will allow you to load tiny amounts of the total data at once.

/**
 * input: prependItemToArrayCombobox(array('' => 'Select Value'), array(1 => 'US', 2 => 'VN'));
 * output: Object ('' => 'Select Value', 1 => 'US', 2 => 'VN' )
 */
function prependItemToArrayCombobox ($result, $array) {
  if (empty($array) === FALSE) { /* add new items to the first if have */
    foreach ($array as $key => $value) {
      if (array_key_exists($key, $result) === FALSE) {
        yield $key => $value;
      }
    }
    foreach ($result as $key => $value) {
      yield $key => $value;
    }
  } else {
    if (empty($result) === FALSE) {
      foreach ($result as $key => $value) {
        yield $key => $value;
      }
    }
  }
}

Lưu ý khi cài mongo db 3, php 5.6 cho window

Khi cài mongo db 3, ta cần phải cài php_mongo.dll cho php, kiếm bản download tại https://s3.amazonaws.com/drivers.mongodb.org/php/index.html. Vậy làm sao biết bản nào phù hợp với PHP của mình:

Khi nhìn vào 1 name của mongo, ta xem thử: Continue reading Lưu ý khi cài mongo db 3, php 5.6 cho window