IE6和IE7无法特别稳定执行,因为custom tags 和 hashchange events无法使用



事件绑定机制根据事件自动触发,触发之后进行数据检查,$scope本身提供了一个key/value存储的哈希表。输入事件(比如键盘被按键了,鼠标焦点之类)、浏览器事件(timeout一类)、服务唤起(比如$http一类的)都会导致脏数据检测。顺便有些情况下,比如地址栏被改变了,或者你希望直接改变那里面的数据,就得手动调用 $scope.$apply()。一般情况下不推荐这么做。

4.0 $rootScope对象之妙用


$scope extends $rootScope

看个例子[‘$rootScope’,function($rootScope) { //this will be available to all scope variables $rootScope.includeLibraries = true; //this method will be available to all scope variables as well $rootScope.include = function(libraries) { var scope = this; //attach each of the libraries directly to the scope variable for(var i=0;i<libraries.length;i++) { var key = libraries[i]; scope[key] = getLibrary(key); } return scope; }; }]);


App.controller(‘SomeCtrl’, [‘$scope’, function($scope) { if($scope.includeLibraries) { //the flag was set in the $rootScope object $scope = $scope.include([‘plugin1’, ‘library1’]); } }]);

5.$apply 和 $digest 和 $$phase

如果在angularjs中引入了第三方类库,你需要有个额外的功能监视数据的变化,比如第三方框架使用了某些动作改变页面数据,这时候需要调用 $scope.$apply(),这个动作意味着调用了$watch把所有的变量变化都监控了一下,本来这件事是系统后台调用的。

部分情况下这个动作可能会抛出异常,因为后台此时正在运行一个digest,为了避免这种情况的发生,需要使用一个全局对象 $scope.$$phase来判断当前是否有后台进行的数据更新操作。

于是为了稳妥起见我们可以自己使用 下面的安全更新操作

//when you add it to the $rootScope variable, then it’s accessible to all other $scope variables. $rootScope.$safeApply = function($scope, fn) { fn = fn || function() {}; if($scope.$$phase) { //don’t worry, the value gets set and AngularJS picks up on it… fn(); } else { //this will fire to tell angularjs to notice that a change has happened //if it is outside of it’s own behaviour… $scope.$apply(fn); } }; //and you can run it like so. $scope.some_value = ‘value…’; $scope.$safeApply($scope, function() { //this function is run once the apply process is running or has just finished });

下面有个例子,这里我们要修改location url所以使用下面的代码

//be sure to inject $scope and $location somewhere before this var changeLocation = function(url, force) { //this will mark the URL change $location.path(url); //use $location.path(url).replace() if you want to replace the location instead $scope = $scope || angular.element(document).scope(); if(force || !$scope.$$phase) { //this will kickstart angular if to notice the change $scope.$apply(); } };


如果现在有个用户动作需要影响几乎所有的controller和directive的话,那就需要使用$emit, $on and $broadcast


//get the topmost scope var $scope = angular.element(document).scope(); //logout event var logoutEvent = ‘logout’; var logoutArgs = [‘arg’]; $scope.$broadcast(logoutEvent, logoutArgs); //login event var logoutEvent = ‘logout’; var logoutArgs = [‘arg’]; $scope.$broadcast(logoutEvent, logoutArgs);


// //in your controller


App.controller(‘Ctrl’, [‘$scope’, function($scope)

{ $scope.$on(‘logout’, function(args) { alert(‘bye bye’); });

$scope.$on(‘login’, function(args) { alert(‘hello there’); }); }]);


// //in your directive // App.directive(‘sessionStatus’, function() { return function($scope, element, attrs) { $scope.$on(‘login’, function() { element(‘html’, ‘You are logged in!’); }); $scope.$on(‘logout’, function() { element(‘html’, ‘You are logged out!’); }); }; });


App.controller(‘Ctrl’, [‘$scope’, function($scope) { $scope.onLogoutClick = function() { $scope.$emit(‘logout’); } }]); //upper $scopes will respond to this with the same $on method.

7.0 为router上的controller加上点附加处理功能

example of it:

//checkout the route code below first before reading this
App.controller('Ctrl', ['$scope', '$http', 'argument1', 'argument2', 'argument3',
                function($scope,   $http,   argument1,   argument2,   argument3) {
  alert(argument1); //someDependeny's value or toString method
  alert(argument2); //"some value"
  alert(argument3); //the value returned from GET /path/to/some/url

//here's where the magic happens
App.config(['$routeProvider',function($routeProvider) {
    templateUrl: '/path/to/some/template.html',
    controller: Ctrl,
    resolve: {
      // this is a registered dependency and works the same
      // as a dependeny injection would within a controller
      argument1: 'someDependency', 

      //this is resolved instantly since there is nothing going on
      argument2: function() { return 'some value'; }, 

      argument3: function() {
        return $http.get('/path/to/some/url',function(response) {
          //this is what is returned as the value for argument3

When the application makes it’s way to the path /some/page/with/an/:id



The $route variable can also be injected directly into the controller and this can be used to fetch information about the current route:

App.controller('Ctrl', ['$route', function($route) {
  $route.current.templateUrl; //the URL of the template
  $route.current.params; //same as $routeParams
  $route.current.controller; //the name of the controller (Ctrl)



your application.

App.factory('myHttp',['$http',function($http) {
  return function() {
    get : function(url, success, fail) {
      $http.get(url).success(function(response) {

//this service can now be called by doing...
$myHttp.get('/path', function(data) {

Also, below is a description of how data is shared between services within the same model.

App.factory('myFoo',['$http',function($http) {
  //any variables defined in this area will be ACCESSIBLE
  //within the any of the other services which are defined
  //within the same module. So if a variable called foo...
  var foo = 'bar';
  //then foo can be accessed in another service. Be sure to
  //keep this in mind since it's hard to debug
  return foo;

App.factory('myBar',['$http',function($http) {
  var bar = 'bar2';
  return foo.toString() + bar; //this should return either bar2 or barbar2

You can also inject any of your own services into any other services when created; this is very useful for code reuse and testing.


9.0 ngshow什么的改变css

The same effect can be created by using angular

<div class="session">
  <span class="admin" data-ng-show="isAdmin">Hello Adminspan>
  <span class="admin" data-ng-hide="isAdmin">Hello Userspan>

Just be sure to set the binding value

$scope.isAdmin = true; //or false or whatever

This works, but when the page is still downloading (when first loaded) you may see both values at the same time so to get around this just use cloaking.

<div class="session ng-cloak">...div>

And define the CSS for it as well:

.ng-cloak {
  /* this will change to block when scope and angular is ready */

Oh! And one more thing. If you wish to set the isAdmin value directly into your HTML, then do the following using the data-ng-init:

<div class="session ng-cloak" data-ng-init="isAdmin=false;">
  <span class="admin" data-ng-show="isAdmin">Hello Adminspan>
  <span class="admin" data-ng-hide="isAdmin">Hello Userspan>

The data-ng-init attribute is useful for pre-setting values


route is not recognized within your application.

  controller : ErrorCtrl
  redirectTo : '/404'

then you can capture the event within your scope by doing the following:['$rootScope','$location',function($rootScope, $location) {
  $rootScope.$on("$routeChangeError", function (event, current, previous, rejection) {
    //change this code to handle the error somehow

set a custom service to wrap all your AJAX calls then you can catch errors before they’re passed onto other parts of your application.

App.factory('myHttp',['$http','$location',function($http, $location) {
  var onEmpty = function() {
    window.location = '/404';

  return function() {
    get : function(url, success, fail) {
      $http.get(url).success(function(response) {
        var data =;
        if(!data) {

Be sure to only use this method when you access resources and data that is required within your application (like JSON data for a specific view).

11 使用$index在循环中获取循环变量进度

To get access to the index of a loop in angular you can access it from the $index value directly.

  <li data-ng-repeat="option in options">
    <h2>Option #{{ $index + 1 }}: {{ option.value }}h2>

Keep in mind that there are also other options available such as $first, $middle, and $last. All of these and more are covered within the



To keep track of the URL when it changes, you will need to setup a polling event.['$rootScope', '$location', function($rootScope, $location) {
    function() { return $location.path() },
    function(path) {
      //new path!

Additionally you can set these events explicitly within your scope variable['$rootScope', function($rootScope) {
  $rootScope.$on('$locationChangeStart', function(event, newUrl) {
    alert('new location');


App.filter(‘my’, function() {
return function(data) {
return data;
You can use of these filters directly in your HTML:

<span class=”some-data”>{{ value | my }}<span>
Or you can also access these filters directly in your services and controllers via dependency injection.

App.factory(‘someService’, [‘$filter’, function($filter) {
return function(data) {
return $filter(‘my’)(data);


<form novalidate class=”simple-form”>
<ol class=”fields”>
<label for=”input-name”>Name:</label>
<input id=”input-name” type=”text” data-ng-model=”name” />
<label for=”input-email”>Email:</label>
<input id=”input-email” type=”email” data-ng-model=”email” />
<button data-ng-click=”submit()”>Submit</button>



Ideally you wouldn’t stick the english translations directly into your own webapge so you can switch this so that translations are looked up in a global translation lookup table.

You would have to define your own lookup since this is something angular doesn’t provide by itself.

var LOOKUP = {
‘’ : ‘No have no messages in your inbox’,
‘’ : ‘You have one message in your inbox’,
‘messages.many’ : ‘You have %messagesCount% messages in your inbox’
var translate = function(key, args) {
var data = LOOKUP[key];
if(data) {
for(var key in args) {
var value = args[key];
key = ‘%’ + key + ‘%’;
data = data.replace(key,value);
return data;
return ”;


<!– this shows up as Sep 9, 2012 –>
<span class=”string-date”>{{ site.curl_left }} ‘2012-09-01′ | date:’medium’ {{ site.curl_right }}</span>

<!– same thing but longer and using a variable –>
<span class=”string-date”>{{ site.curl_left }} someDateVariable | date:’fullDate’ {{ site.curl_right }}</span>

<!– and you can set your own –>
<span class=”string-date”>{{ site.curl_left }} anotherDateVariable | date:’EEEE, MMMM d,y’ {{ site.curl_right }}</span>
You can also access the date filter directly within your controllers and services with use of the $filter service.

var dateFilter = $filter(‘date’);
var mediumDateString = dateFilter(‘2012-09-01’, ‘medium’);
var fullDateString = dateFilter(someDateVariable, ‘fullDate’);
var anotherDateString = dateFilter(anotherDateVariable, ‘EEEE, MMMM d,y’);





Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s