angularJS 小结

Modules

 

When declaring a module, we need to pass two parameters to the method. The first is the name of the module we are creating. The second is the list of dependencies,

otherwise known as injectables.

angular.module('myApp', []);

Organizing Dependencies with Modules

 

Generically, we call these dependencies services, as they provide specific services to our application


Angular comes with many services like 


$location, for interacting with the browser’s location,

$route, for switching views based onlocation (URL) changes, and 

$http, for communicating with servers

 

An example:

 

var shoppingModule=angular.module('ShoppingModule',[]);
shoppingModule.factory('shopList',function(){
var items={};
items.query=function(){
// In real apps, we'd pull this data from the server...
return [
{title: 'Paint pots', description: 'Pots full of paint', price: 3.95},
{title: 'Polka dots', description: 'Dots with polka', price: 2.95},
{title: 'Pebbles', description: 'Just little rocks', price: 6.95}
];
};
return items;
});
var ShoppingController=function(shopList,$scope){
$scope.items=shopList.query();
}

Displaying Text

{{greeting}}

Then there’s an attribute-based directive called ng-bind:

Both are equivalent in their output

For the data binding you do in your index.html page, however, use ng-bind instead. That way,your users will see nothing until the data has loaded 

function StartUpController($scope) {
$scope.funding = { startingEstimate: 0 };
computeNeeded = function() {
$scope.funding.needed = $scope.funding.startingEstimate * 10;
};
$scope.$watch('funding.startingEstimate', computeNeeded);
}

In this way, funding.needed will automatically update whenever funding. starting Estimate changes


错误小结:

function DeathrayMenuController($scope) {
$scope.menuState.show = false;//未初始化menuState;应在前添加语句$scope.menuState={ };
$scope.toggleMenu = function() {
$scope.menuState.show = !$scope.menuState.show;
};
}

Separating UI Responsibilities with Controllers

Nested(嵌套) controllers that can share model and functions through an

inheritance tree\

...

the actual nesting happens in scopes. The $scope passed to a nested controller prototypically inherits from its parent controller’s $scope.

Publishing Model Data with Scopes

1.There are also some indirect ways to set up the model from the template itself

setting properties in expressions is the same as setting a property of the controller’s scope.

2.Using ng-model on a form input.

ng-model 

the ng-model attribute, which tells AngularJS to create a two-way binding between the value of the input element and the done property of the corresponding data object

 

Exa:


{{item.action}}

{{item.done}}

Observing Model Changes with $watch

$watch(watchFnwatchActiondeepWatch)

watchFn

This parameter is a string with an Angular expression or a function that returns

the current value of the model that you want to watch

watchAction

This is the function or expression to be called when the watchFn changes

deepWatch

If set to true, this optional boolean parameter tells Angular to examine each property within the watched object for changes

 

Examples:

Way-1:

var calculateTotals = function() {
var total = 0;
for (var i = 0, len = $scope.items.length; i < len; i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
$scope.bill.total=total;
$scope.bill.discount=total>100?10:0;
$scope.bill.subtotal=total-$scope.bill.discount;
}
$scope.$watch('items',calculateTotals,true);

Way-2:

 

$scope.$watch(function(){
var total = 0;
for (var i = 0, len = $scope.items.length; i < len; i++) {
total = total + $scope.items[i].price * $scope.items[i].quantity;
}
$scope.bill.total=total;
$scope.bill.discount=total>100?10:0;
$scope.bill.subtotal=total-$scope.bill.discount;
});

Watching multiple things

if you’ve got an object with two properties a and b in your scope, and

want to execute the callMe() function on change

1.Put them into an array or object and pass in deepWatch as true.

$scope.$watch('things.a + things.b'callMe(...));

2.Watch a concatenated value of the properties

$scope.$watch('things'callMe(...), true);

 

Building the Angular Service

we’ll use a service. A service persists across controllers for the duration of the application’s lifetime and is the appropriate place for us to hide business logic away from the controller.

We need to configure our app when it boots up, so we need to create our service using the .provider() method. This method is the only service creation method that we can inject into .config() functions.

.provider('Weather', function() {
     var apiKey = "";
     this.setApiKey = function(key) {
            If(key) 
                  this.apiKey = key;
      };
      this.$get = function($http) {
           return {
                      // Service object
           }
      }
})


Firstly a provider is a function that must return an object containing the $get property. The mentioned $get property is a factory function, that when invoked should return a service instance.We can think of providers as objects that embed factory functions in their $get property

 

.config(function(WeatherProvider) {
       WeatherProvider.setApiKey('');
})


The important thing to notice here is a dependency on the WeatherProvider objects with the Provider suffix representing the recipes that are ready to be executed


controller中调用 

.controller('myCtrl',function($scope, Weather){
      $scope.hi = Weather;
});

 

Changing Views with Routes and $location

First of all:We need to reference angular-route in our HTML after we reference Angular itself.



we need to reference the ngRoute module as a dependency in our app module:

 

angular.module('myApp',['ngRoute']);

You create routes in your application by calling functions on the $routeProvider service as a configuration block. It goes something like this pseudo-code:

var someModule = angular.module('someModule', [...module dependencies...])
	someModule.config(function($routeProvider) {
		$routeProvider
			.when('url', {
				controller:aController, 
				templateUrl:'/path/to/tempate'
			})
			.when(...other mappings for your app...)
			.otherwise(...what to do if nothing else matches...);
	)};


$routeParams

if we start a route param with a colon (:), AngularJS will parse it out and pass it into the $routeParams

$routeProvider
	.when('/inbox/:name', {
		controller: 'InboxController',
		templateUrl: 'views/inbox.html'
	})

then Angular will populate the $routeParams with the key of :name, and the value of key will be populated with the value of the loaded URL

If the browser loads the URL /inbox/all, then the $routeParams object will look like:

{ name'all' }  

As a reminder, to get access to these variables in the controller, we need to inject the $routeProvider in the controller:

 

app.controller('InboxController', function($scope, $routeParams) {
	// We now have access to the $routeParams here
	//取出name值使用 $routeParams.name 
});

$routeProvider

Route

Resolve: An optional map of dependencies which should be injected into the controller

· key – {string}: a name of a dependency to be injected into the controller.

· Factory {string|function}: If string then it is an alias for a service. Otherwise if function, then it is injected and the return value is treated as the dependency. Use $route.current.params to access the new route parameters

$routeProvider
	.when('/', {
		controller: 'ListCtrl',
		resolve: {
			recipes: function(MultiRecipeLoader) {//recipes注入到ListCtrl控制器中
				return MultiRecipeLoader();//factory 服务 返回 promise 类型数据
			}
		},
		templateUrl:'views/list.html'
   })

ListCtrl

 

app.controller('ListCtrl', ['$scope', 'recipes',function($scope, recipes) {
	$scope.recipes = recipes;
}]);

Responding to Route Changes

The Events Defined by the $route Service

$routeChangeStart:  Triggered before the route is changed

$routeChangeSuccess:  Triggered after the route has changed

$routeUpdate:  Triggered when the route is refreshed; this is tied to the   reloadOnSearch configuration property, which I describe in   the “Configuring Routes” section

$routeChangeError:  Triggered if the route cannot be changed

exa:

$scope.$on("$routeChangeSuccess", function () {
// ...statements for responding  go here...
});

ngView

ngView is a directive that complements(补足,完善) the $route service by including the rendered template of the current route into the main layout (index.html) file. Every time the current route changesthe included view changes with it according to the configuration of the $route service.

 

templateUrl

templateUrl – {string=|function()=} – path or function that returns a path to an html template that should be used by ngView.

格式:

同一路径下:templateUrl:'list.html'

不同路径:templateUrl:'views/list.html'或者

使用绝对路径 templateUrl:’../app/views/list.html


Directives

API Overview

A basic pseudo-code template for creating any directive follows:

 

var myModule = angular.module(...);
myModule.directive('namespaceDirectiveName', function factory(injectables) {
	var directiveDefinitionObject = {
		restrict: string,
		priority: number,
		template: string,
		templateUrl: string,
		replace: bool,
		transclude: bool,
		scope: bool or object,
		controller: function controllerConstructor($scope,$element,$attrs,$transclude){...},
		require: string,
		link: function postLink(scope, iElement, iAttrs) { ... },
		compile: function compile(tElement, tAttrs, transclude) {
			return {
				pre: function preLink(scope, iElement, iAttrs, controller) { ... },
				post: function postLink(scope, iElement, iAttrs, controller) { ... }
			}
		}
	};
	return directiveDefinitionObject;
});

The name of the directive should always be pascalCased(驼峰式), and the function we provide should return an object

 

In our case, we declare the directive in HTML using my-directive, the directive definition  must be myDirective

 

The following are valid formats for declaring the directive we built above:


restrict:

The restrict option tells Angular which declaration format(s) to look for

when compiling our HTML.

we can specify that we want our directive to be invoked if it is an element (E), an attribute (A), a class (C), or a comment (M):

If you omit(忽略) the restrict property, the default is A, and your directive can be used only as an attribute.

template:

Specify an inline template as a string. Not used if you’re specifying your template as a URL

 

replace (boolean)

.directive('someDirective' function() {
	return {
		template: '
some stuff here
' } })

The result when the directive is invoked will be

some stuff here

If we set replace as true:

.directive('someDirective' function() {
	return {
		replace: true // MODIFIED
		template: '
some stuff here
' } })

then the result when the directive is invoked will be:

some stuff here

Scope Option (boolean|object)

  scope is optional. It can be set to true or to an object, {}. 

By default, it is set to false.

  When scope is set to true, a new scope object is created that prototypically inherits from its parent scope.

.directive("scopeDemo", function () {
	return {
		template:"
Name:
", scope:true } })

 


  To create a directive with isolate scope we’ll need to set the scope property of the directive to an empty object, {}. Once we’ve done that, no outer scope is available in the template of the directive

 

This is the consequence of the isolated scope; because there is no inheritance from the controller’s scope, there are no values defined for any of the properties specified by the ng-model directive

 

One-way binding

The first change is in the scope definition object, where I set up a one-way mapping between an attribute and a property in the directive scope

scope: {
	local: "@nameprop"
}

The second change is to define the nameprop attribute on the elements to which I apply my custom directive,

The final change is to update the template so that it displays the value of the local property

Data Value: {{local}}

Two-way binding

To create a two-way binding, I replace the  @  character with the  =  character when I create the isolated scope

from the previous example:

scope: { local: "@nameprop" }

becomes this:

scope: { local: "=nameprop" }

However.,When using a one-way binding, I provided a binding expression complete

with the {{ and }} characters, but AngularJS needs to know which property to update with changes in a two-way binding, so I have to set the attribute value to a property name,

 

Transclude(内嵌)

When set to true, the directive will delete the original content, but make it available for reinsertion within your template through a directive called ng-transclude

appModule.directive('hello', function() {
	return {
		template: '
Hi there
', transclude: true }; });

applying it as:

hello>Bob

We would see: “Hi there Bob.”

 

link

We use the link option to create a directive that manipulates the DOM.

 

Compile

As we are creating a new element, we need to use the compile function rather than just the link function and a template, since our 

     element cannot be nested underneath an  element

     

    Validating User Input

    we can access the validation state of the form through a property called $valid. Angular will set this to true when all the inputs in the form are valid

    Sign Up

    {{message}}
    First name:
    Last name:
    Email:
    Age:

     
      

    Communicating with Servers

    $http

    function Controller($scope,$http){
    	$http.get('http://localhost:8080/stu_restful/rest/student/getTheStudent?name=coco')
    	.success(function(data,stastus,headers,config){
    		$scope.student=data.student;
    	});
    }

    或者

    $http.get('http://localhost:8080/stu_restful/rest/student/getTheStudent',
    			{params:{name:'coco'}}
    		).success(function(data,stastus,headers,config){
    			$scope.student=data.student;
    		});

    第三种:

    $http({
    	method: 'GET',
    	url:"http://localhost:8080/stu_restful/rest/student/getTheStudent",
    	params:{name:'zc'}
    }).success(function(data,stastus,headers,config){
    	$scope.student=data.student;
    });


    Use Promise

     

    What’s a Promise

    A promise is a method of resolving a value (or not) in an asynchronous manner.Promises are incredibly useful in dealing with remote objects, and we can think of them as a proxy for our remote objects.


    the $http method returns a promise object, we can use the then method to handle the callback when the response is ready

     

    angular.module('myApp',[])
    	.controller('Controller',function($scope,$http){
    		var promise=$http({
    			method:'GET',
    			url:'http://localhost:8080/stu_restful/rest/student/getTheStudent',
    			params:{name:'zc'}
    		});
    		promise.then(function(resp){
    			var data=resp.data;
    			$scope.student=data.student;
    		},function(resp){
    			console.log("error");
    		});
    });

    Returned  promise  is like this:

    Object {data: Object, status200headers: function, config: Object}

    取出数据 运用 promise.data 即可


    使用RESTful资源 

    The ngResource module is an optional Angular module that adds support for interacting with RESTful back-end data sources.

    src="js/vendor/angular.js">

    src="js/vendor/angular-resource.js">

     

    we need to reference the ngResource module as a dependency in our app module:

    angular.module('myApp', ['ngResource']);

     

    //The $resource service itself is a factory that creates a resource object. The returned $resource object has methods that provide a high-level API to interact with back-end servers

    var User = $resource('/api/users/:userId.json', 
    {
    userId: '@id'
    });


    We can think of the User object as an interface to our RESTful services

    User.get({
    	id: '123'
    }, function(resp) {
    	// Handle successful response here
    }, function(err) {
    	// Handle error here
    });
    

    • Users.query(params, successcb, errorcb): It issues an HTTP GET request and expects an array in the JSON response. It is used to retrieve

    a collection of items.

    • Users.get(params, successcb, errorcb): It issues an HTTP GET request and expects  an object in the JSON response. It is used to retrieve a single item.

    • Users.save(params, payloadData, successcb, errorcb): It issues an HTTP POST  request with request body generated from the payload.

    • Users.delete(params,successcb, errorcb) (and its alias: Users.remove): It issues an HTTP DELETE request.

     

    $resource instances

    • $save()

    • $remove()

    • $delete()

     

    // Using the $save() instance methods

    User.get({id: '123'}, function(user) {
    	user.name = 'Ari';
    	user.$save(); // Save the user
    });

    // This is equivalent to the collection-level

    // resource call

    User.save({id'123'}, {name'Ari'});

    $resource Instances Are Asynchronous

    // $scope.user will be empty

    $scope.user User.get({id'123'});

     

    We can wait for the data to come back as expected using the callback method that the methods provide:

    User.get({id: '123'}, function(user) {
    $scope.user = user;
    });


    例子:

     

    angular.module('myApp', ['ngResource'])
    	.factory('stuResource', ['$resource', function($resource) {
    		return  $resource('http://localhost:8080/stu_restful/rest/student/getTheStudent:userId'
    					,{userId:'@id'}
    				);
    	}])
    	.controller('Controller',function($scope,stufac){
    		stuResource.get({name: 'zc'}, function(user) {
    			console.log(user);
    			$scope.student= user.student;
    		});
    	});

    The  :id  part, which corresponds to the map object that is the second argument, tells AngularJS that if the data object it is working with has an id property, then it should be appended to the URL used for the Ajax request.

     

    What about that second object? The {id: @id}? Well, as they say, a line of code is

    worth a thousand explanations, so let’s take a simple example.

    Say we have a recipe object, which has the necessary information already stored

    within it, including an id.

    Then, we can save it by simply doing the following:

    // Assuming existingRecipeObj has all the necessary fields,

    // including id (say 13)

    var recipe new Recipe(existingRecipeObj);

    recipe.$save();

    This will make a POST request to /recipe/13.

    The @id tells it to pick the id field from its object and use that as the id parameter.

     

    restful ,$resource POST 请求实例:

    //POST test
    var addStu = $resource('/stu_restful/rest/student/updateStu:sName',
    	//带连字符 “_”的 参数 命名采用驼峰式
    	{s_name:'@std_name'}
    );
    addStu.save({std_name: 'zc'}, function(resp) {
    		console.log(resp);
    		//$scope.student= resp.student;
    	},function(err){
    		console.log(err);
    	});

    传递多个参数:

    var addStu = $resource('/stu_restful/rest/student/updateStu:sName:sLesson', 
    	//带连字符 “_”的 参数 命名采用驼峰式
    	{s_name:'@std_name',s_lesson:'@std_lesson'}
    );
    addStu.save({std_name: 'zc',std_lesson:'Chinese'}, function(resp) {
    		console.log(resp);
    		//$scope.student= resp.student;
    	},function(err){
    		console.log(err);
    	});

    对比:

    1.

    var User = $resource('/stu_restful/rest/student/student1/:Uid', {Uid:'@stu_id'}

    );

    User.get({stu_id2})

     

    返回的Url:http://localhost:8080/stu_restful/rest/student/student1?stu_id=2

     

    2.

    var User=$resource('/stu_restful/rest/student/student1/:Uid'

    {Uid :'@stu_id'}

    );   

    User.get({Uid:2},

    返回的Url:http://localhost:8080/stu_restful/rest/student/student1/2


    · HTTP GET "class" actions: Resource.action([parameters], [success], [error])

    · non-GET "class" actions: Resource.action([parameters], postData, [success], [error])

    · non-GET instance actions: instance.$action([parameters], [success], [error])

     

    项目中出现的问题与解决:

     

    1.List 转化 json 数组 

     public String getStudents() {
        stuList=studentService.getStudentList("student");
        JSONArray json=JSONArray.fromObject(stuList);
    	return json.toString();
     }

    2.实现数据的编辑并保存,id唯一情况下 delete+post方法编辑并保存数据,替代不能使用的put方法(时好时坏。。。)

     

    app.controller('EditCtrl', ['$scope''$location''recipe',

        function($scope, $location, recipe) {

    $scope.recipe = recipe;

    //console.log(recipe);

    var Id =recipe.id;//保存id

    $scope.save = function() {

    recipe.$remove(function(res) {//删除原数据

    });

    //console.log(recipe);

    $scope.recipe.$save(function(res) {//保存新数据

    $location.path('/view/' + Id);

    });

    };

    }]);

    3.增加新数据,并使id号自增

     

    app.controller('NewCtrl',['$scope','$location','Recipe','recipes',function($scope, $location, Recipe,recipes) {

      //console.log(recipes.length);

      var id=recipes.length;//数据库中存在数据条数即为

      $scope.recipe = new Recipe({

        ingredients: [ {} ]

      });

      $scope.recipe.id=id;

      $scope.save = function() {

        $scope.recipe.$save(function(recipe) {

          $location.path('/view/' + id);

        });

      };

    }]);

     

     

    GetRecipe 项目分析

    var services = angular.module('guthub.services', ['ngResource']);
    	services.factory('Recipe', ['$resource',function($resource) {
    			return $resource('/stu_restful/rest/Recipe/recipes/:id', {id: '@id'});
    	}]);
    	services.factory('MultiRecipeLoader', ['Recipe', '$q',function(Recipe, $q) {
    			return function() {
    				var delay = $q.defer();
    				Recipe.query(function(recipes) {
    					delay.resolve(recipes);
    				}, function() {
    					delay.reject('Unable to fetch recipes');
    				});
    				return delay.promise;
    			};
    	}]);

    With just that single line of code—return $resource—(and of course, a dependency

    on the guthub.services module), we can now put Recipe as an argument in any of

    our controllers, and it will be injected into the controller.

     

    The Templates(视图界面)

    There is no ng-controller defined,and there really was no Main Controller defined. This is where route mapping comes into play.

    The / route redirected to the list template and had the List Controller associated with it. Thus, when any referencesare made to variables and the like, it is within the scope of the List Controller.


    ng-submit


    The final thing to note is the ng-submit directive on the form. The directive states that the edit() function on the scope is called in case the form is submitted. The form submission happens when any button without an explicit function attached (in this case, the Edit button) is clicked

     

    provider, factoryservice

    provider, factoryservice都是写Angularjsservice中常用的关键字,很容易混淆,写了一个简单的例子显示他们之间的区别:

    分别用servicefactoryprovider定义三个service

    var wtcModule = angular.module('wtc', []);

    wtcModule.service('testService',function(){

         this.lable = 'this is service';

    });

    wtcModule.factory('testFactory', function () {

         return{

            lable: function(){return 'this is factory';}

        }

    });

    wtcModule.provider('testProvider', function(){

        this.$get = function(){

            return 'this is provider';

        }

    });

    在页面上留出三个占位符:

        

    {{ output1 }}

        

    {{ output2 }}

        

    {{ output3 }}

    写好outputCtrl:

    var wtcModule = angular.module('wtc');

    wtcModule.controller('outputCtrl', function($scope,testService, testFactory, testProvider){

        $scope.output1 = testService.lable;

        $scope.output2 = testFactory.lable();

        $scope.output3 = testProvider;

    });

    最后页面的显示结果为;

    说明:

    注入service,相当于注入service定义时的function实例

    Services are singleton objects that provide any functionality 

    注入factory,相当于注入factory定义时的函数调用入口。 

    factory function returns a service object

    注入provider,相当于注入provider$get定义的函数实例的调用

    angular.module( 'customService' , []) 
    	.provider('logService',function(){
    		return {
    			messageCountenable:function(setting){}
    			$get: function(){
    				return {
    					messageCount:0,
    					log: function(msg){
    						console.log("(LOG + " + this.messageCount++ + ") " + msg);
    					}
    				};
    			}
    		}
    	});


    Provider:

    The factory function is required to return a provider object that defines a method called $get, which in turn is required to return the service object.

     

    AngularJS makes the provider object available for dependency injection, using the name of the service combined with the word Provider, so for the example the provider object can be obtained by declaring a dependency on logServiceProvider.

    angular.module("exampleApp", ["customDirectives", "customServices"])
    	.config(function(logServiceProvider){
    		logServiceProvider.
    	}) 


    Mobile

    Beginning with Angular version 1.2.2, we now have the ability to use touch events using the new ngTouch module

    Either way, we need to reference the library in our index.html as a script:

    src="/bower_components/angular-touch/angular-touch.js">

    Finally, we need to include ngTouch as a dependency in our app:

    angular.module('myApp', ['ngTouch']);

     

    ngSwipe

    One of the nice features the ngSwipe* directives give us is that they work both with touch-based devices as well as with mouse clicking and dragging.

     

    Example:

      ng-repeat="mail in emails">

      ng-show="!mail.showActions"

      ng-swipe-left="mail.showActions=true">

      class="from">

      From: {{ mail.from }}

class="body">

{{ mail.body }}

ng-show="mail.showActions"

ng-swipe-right="mail.showActions=false">

class="actions">

  •  

     

     

    MVC pattern:

    Common Design Pitfalls(陷阱):

    1.Putting the Logic in the Wrong Place

    • Putting business logic in views, rather than in controllers

    • Putting domain logic in controllers, rather than in model

    • Putting data store logic in the client model when using a RESTful service

    here are the three rules:

    • View logic should prepare data only for display and never modify the model.

    • Controller logic should never directly create, update, or delete data from the model.

    • The client should never directly access the data store

     

    对比 

    angular.module("sportsStore", [ ])  和 angular.module("sportsStore")

    第二个: Omitting the second argument tells AngularJS that you want to locate a module that has already been defined.

    In this situation, AngularJS will report an error if the module specified doesn’t exist, so you need to make sure the module has already been created.

     

    The Fluent API

    The result of the methods defined by the Module object is the Module object itself. 

    (I call the angular.module method and get a Module object as the result)

    This is an odd-sounding but neat trick that allows for a fluent API, where multiple calls to methods are chained together

     

    angular.module("exampleApp", [])

    .controller(...)

    .config(...)

     

    Filters 

    Filters  are themselves functions, which receive a data value and format it so it can be displayed.

    myApp.filter('dayName',function(){
    	var dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday","Thursday", "Friday", "Saturday"];
    	return function(input){
    		return angular.isNumber(input)?dayNames[input]:input;
    	};
    });

    The data binding or expression is followed by a bar (the | character) and then the name of the filter, as follows:

    Today is {{day | dayName}}

    I have added a $filter argument to my directive factory function, which tells AngularJS that I want to receive the filter service object when my function is called. The $filter service gives me access to all of the filters that have been defined.


    the Module Life Cycle

    var myApp = angular.module("exampleApp",["exampleApp.Controllers", "exampleApp.Filters",
    												"exampleApp.Services", "exampleApp.Directives"]);
    myApp.constant("startTime", new Date().toLocaleTimeString());
    myApp.config(function (startTime) {
    	console.log("Main module config: " + startTime);
    });
    myApp.run(function (startTime) {
    	console.log("Main module run: " + startTime);
    });
    ............
    angular.module("exampleApp.Services", [])
    	.service("days", function (nowValue) {
    	.........
    	})
    	.config(function() {
    		console.log("Services module config: (no time)");
    	})
    	.run(function (startTime) {
    		console.log("Services module run: " + startTime);
    	});


    Services module config: (no time)

    Main module config: 16:57:28

    Services module run: 16:57:28

    Main module run: 16:57:28

     

    The config method accepts a function that is invoked after the module on which the method is called is loaded. The config method is used to configure a module, usually by injecting values that have been obtained from the server, such as connection details or user credentials.

    The run method also accepts a function, but it will be invoked only when all of the modules have been loaded

    You can see this in the way that the callbacks for the exampleApp.Services module are made

    before those for the main exampleApp module. This allows modules to configure themselves before they are used to resolve module dependencies.

    I am able to use the startTime constant in three of the four callbacks, but I can’t use in the config callback for the exampleApp.Services module because the module dependencies have yet to be resolved. At the moment the config callback is invoked, the startTime constant is unavailable.

     

    ng-repeat

    1.

    {{item.action}}

    {{item.complete}}

     

    2

    {{prop}}

    3

    {{ key }}={{ value }}

    don’t try to use apply the ng-include directive as a void element (in other words,  src="'table.html'" />)

    Form

    novalidate :

    To disable the browser validation support and enable the AngularJS features, I have added the novalidate attribute to my form element, which is defined by the HTML5 specification and tells the browser not to try to validate the form itself, allowing AngularJS to work unhindered

     

    邮箱验证

     

    ng-show="myForm.userEmail.$invalid && myForm.userEmail.$dirty">

    Please enter a valid email address

    Please enter a value


    Data Inheritance

    when you use the ng-model directive to modify such a property, AngularJS

    checks to see whether the scope has a property of the right name and, if not, assumes you want to implicitly define it.The effect is to override the property value

    section. The reason that editing the contents of a child input element prevents the Reverse button from working is that there are now two dataValue properties—one defined by the top-level controller and one by the child you edited. The reverseText behavior is defined by the top-level controller, and it operates on the dataValue defined in the top-level scope, leaving the child’s dataValue property unaltered.

    This doesn’t happen when you assign an object to the scope and then define your data properties on that object.This is because JavaScript implements what is known as prototype inheritance

    What is important is the knowledge that defining properties directly on the scope like this:

    ...
    $scope.dataValue = "Hello, Adam";
    ...

    means that using the ng-model directive will create local variables, while using an object as an intermediary, like this:

    ...
    $scope.data = {
    	dataValue: "Hello, Adam"
    }
    ...

    ensures that ng-model will update the data values defined in the parent scope

    If you want a value that is initially shared but will be copied when modified, then define your data properties directly on the scope. To ensure that there is only one value

    then define your data properties via an object

    你可能感兴趣的:(前端)