In the last section, after you've finished the basics of application development, such as data binding, adding styles, Next, you'll be in the app, with some events related to controlling it ...
One, the separation of the UI and controller
We need to clarify the three roles of the controller in the application:
"1" Sets the initial state in the app model
"2" exposes functions and models through $scope objects to the view (UI template)
"3" monitor other parts of the model that have changed and make corresponding actions
II. publishing the data model in scope
The $scope object passed to the controller is a mechanism for exposing the model data to the view. There may be other data in the application we build, but when passing these properties through scope, angular only considers the model part.
In the previous litchi, we often see the data instance built by $scope, which is done in the controller, where we can also build models from templates through some indirect methods.
1. Use expressions: Because expressions are executed in the controller that can be associated with them, setting properties in an expression is consistent with setting properties in the controller. That can be done as follows
<button ng-click= ' count=3 ' >set count to Three</button>
It is equivalent to
<div ng-controller= ' countcontroller ' ><button ng-click= ' setcount () ' >set count to Three</button> </div>
Controller definition
function Countcontroller ($scope) {$scope. SetCount = function () {$scope. count=3;}}
2. A data binding via Ng-model
Third, observing model changes with $watch
$watch (WATCHFN, watchaction, Deepwatch)
The function for each parameter details
WATCHFN: This parameter is a function that angualr the expression string or returns the current value of the monitor model, which is executed multiple times
Watchaction: This is a function or expression that, when WATCHFN changes, calls them, in the form of a function, it has watchfn old and new values, and a $scope reference, function in front of functions (Newvalue,oldvalue,scope )
Deepwatch: This is an optional Boolean parameter, if set to TRUE,ANGUALR will monitor the change of each property of the object
The next chestnut is an upgraded version of the previous shopping cart.
<div ng-controller= "Cartcontroller" ><div ng-repeat= "item in Items" ><span>{{item.title}}</span ><input ng-model= "item.quantity" ><span>{{item.price | currency}}</span><span>{{ Item.price * item.quantity | Currency}}</span></div><div>total: {{totalcart () | Currency}}</div><div>discount: {{ Bill.discount | Currency}}</div><div>subtotal: {{Subtotal () | currency}}</div></div>
Cartcontroller:
function Cartcontroller ($scope) {$scope. Bill = {}; $scope. Items = [{title: ' Paint pots ', Quantity:8, Price:3.95},{title: ' Polka dots ', quantity:17, Price:12.95},{title: ' Pebbles ', Quantity:5, price:6.95}]; $scope. Totalcart = function () {var Total = 0;for (var i = 0, Len = $scope. items.length; l < Len; i++) {total = Total + $scope. Items[i].price * $scope. Ite ms[i].quantity;} return total;} $scope. Subtotal = function () {return $scope. Totalcart ()-$scope. Bill.discount;}; function Calculatediscount (newvalue, OldValue, scope) {$scope. Bill.discount = newvalue > 100? 10:0;} $scope. $watch ($scope. Totalcart, Calculatediscount);}
Note: in Totalcart () establish a watch, Totalcart () is used to calculate the total amount of the payment, and whenever it changes, the Watch function calls Calculatediscount (), and we set the appropriate discount for that value. If the total value Da Yu 100$, set the discount to10$, otherwise 0;
The above results
For watch performance, we also need to be aware of some potential performance issues
In the above example, although it can run normally, but if we are in Totoalcart () plus a debug power outage, you will see it is called six times before rendering the page, and in the code we easily track to three times,
1. {{totalcart|currency}} in the template
2.Subtotal () function
3. $watch () function
ANGUALR in order to verify that the transfer model changes have been completely passed, will run more than once, so a total of six times, and this situation is easy to create a cyclic dependency. So we provide the following centralized solutions
One is to create love on each element of the array $watch monitor changes, but this only calculates the total,discount,subtotal in the $scope attribute
<div>total: {{bill.total | currency}}</div><div>discount: {{Bill.discount | currency}}</div> <div>subtotal: {{bill.subtotal | currency}}</div>
Then in the controller, we monitor the elements of the array, and once the array has changed, the function is called to recalculate the total price
function Cartcontroller ($scope) {$scope. Bill = {}; $scope. Items = [{title: ' Paint pots ', Quantity:8, Price:3.95},{title: ' Polka dots ', quantity:17, Price:12.95},{title: ' Pebbles ', quantity:5, Price:6.95}];var calculatetotals = function () { var = 0;for (var i = 0, Len = $scope. items.length; i < Len; i++) {total = Total + $scope. Items[i].price * $scope. items[i].quantity;} $scope. Bill.totalcart = Total, $scope. Bill.discount = total > 100? 10:0, $scope. bill.subtotal = total-$scope. bill.discount;}; $scope. $watch (' Items ', calculatetotals, true);}
Note: Items,items that specifies a string in $scope is executed as an expression in the $scope scope in which it is called
Then, since we were monitoring all the items in the array, Angualar had to make a copy of it for comparison, which could lead to inefficient operation if it encounters a list with many elements.
So we can give $watch only one WATCHFN for recalculating properties.
$scope. $watch (function () {var = 0;for (var i = 0; i < $scope. items.length; i++) {total = Total + $scope. Items[i]. Price * $scope. items[i].quantity;} $scope. Bill.totalcart = Total, $scope. Bill.discount = total > 100? 10:0, $scope. bill.subtotal = total-$scope. bill.discount;});
Iv. injection of the organizational module:
| Function |
Defined |
| Provider (Name,object OR constructor ()) |
Configurable, service with complex logic, available for constructors |
| Factory (name, $getFunction ()) |
A service that is not configurable, has complex logic, defines a function, and returns a service instance when called |
| Service (Name,constructor ()) |
Simple logic for creating a service instance |
Here, we use Factory () using the items example discussed earlier
Create a module to support our shopping viewsvar Shoppingmodule = angular.module (' Shoppingmodule ', []);//Set up the SE Rvice Factory to create our Items interface to the//server-side database shoppingmodule.factory (' Items ', function () {var Items = {};items.query = function () {//In real apps, we ' d pulled 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},{titl E: ' Pebbles ', Description: ' Just little Rocks ', price:6.95}];}; return items;});
V. Filter data with filters
Filters allow you to declare how the data displayed to the user is converted and inserted into your template.
{{expression | filtername:parameter1: ... parametern}}
Where expression is arbitrary, filtername is the name of the filter you want to use, and the parameters passed to the filter are separated by colons.and angular has a few of its own filters such as: Date,number,uppercase, and so on, here is not much introduction, mainly we come to learn if you create a custom filter
The following example constructs a filter called Titlecase with the filter () function to capitalize the first letter of each word in a sentence
var homemodule = angular.module (' Homemodule ', []) homemodule.filter (' Titlecase ', function () {var titlecasefilter = function (input) {var words = input.split ('); for (var i = 0; i < words.length; i++) {Words[i] = Words[i].charat (0). ToU Ppercase () + words[i].slice (1);} Return Words.join (");}; return titlecasefilter;});
The corresponding HTML template<body ng-app= ' homemodule ' ng-controller= "HomeController" >
Assigning values to model variables by controllerfunction HomeController ($scope) {$scope. pageheading = ' Behold the majesty of your page title ';}
Running results such as