You are welcome to discuss and guide:)
Tomorrow day will continue to update this article O (∩_∩) o
Objective
When the built-in directives in Angularjs do not meet our needs, or when we need to create a self-contained unit of functionality that can be used with multiple ANGULARJS programs, we should create custom directives to meet the requirements.
First, create custom directives
I. 1 naming conventions
We want to use the peak camel name when creating the instruction, for example, the instruction is <div unordered-list></div> We need to write this app.directive when we declare the directive (" Unorderedlist ", function() {..}) Similarly, when we want to get the attributes of an element that contains directives, such as <div unordered-list= "Product" ></div> , we also use the camel-like naming convention var attrproduct = attrs["Unorderedlist"]
I. 2 getting data from a scope
scope , element , attrs where, scope The parameter represents the scope of the controller to which the instruction is applied. In a nutshell, scope is the equivalent of the scope $scope of the controller under which the directive is currently scoped. Let's say that our " unorderedlist " directive is under the scope of the Defaultcontroller controller, so how do we get what we need from this scope $scope. Product (Here's an example)
App.controller ("Defaultcontroller", [' $scope ', function ($scope) {$scope. Product = [{name: ' Apples ', Category: ' Fruit ', PR ice:1.20, Expiry:10 ' Bananas ', Category: ' Fruit ', price:2.42, expiry : 7 ' Pears ', Category: ' Fruit ', price:2.02, Expiry:6 "Unorderedlist", function () { return function (scope, element, attrs) {var data = scope[attrs["Unorderedlsit"]] }})
The answer is to set a specific value (here, product) for the attributes of the element that contains the directive, such as <div unordered-list= "Product" ></div> , and then Attrs property gets this specific value var data = scope[attrs["Unorderedlsit"]
One. 3 Breaking the dependency on data properties
For instruction functions, we should minimize the "assumptions" of the code process and enhance the reusability of the instructions by adding specific attributes to the elements that contain the instructions. For example, we "assume" that we have a name in each item in data var data = scope[attrs["Unorderedlsit"] that we obtained in the example above property, we will manipulate our code in this way:
for (var i = 0; i < data.length; i++) { var str = data[i].name // .... "Suppose" has the Name property }
But actually, we should do this. <div unordered-list= "Product" list-property= "name" ></div> we do this by adding another The List-property property and assigns it a specific value of "name" so that we do not need to "assume", thus increasing the efficiency of the instruction
for (var i = 0; i < data.length; i++) { var property = attrs["ListProperty"] C10>var str = data[i].property // .... Do not make "assumptions"}
One. 4 using $eval for calculations
<div unordered-list= "Product" list-property= "price" when the properties of our directive need to work with the filter filters or some other components Currency "></div> For example here, we need an instruction to get the price property, and we need to mate with the filter currency for preprocessing, What should we do? The answer is $eval, by getting the expression and running it through $eval, you get the effect we need. Note: The first parameter of the $eval is the specific expression, and the second argument is the one that is evaluated to the expression.
for (var i = 0; i < data.length; i++) { var propertyexrpession = attrs["ListProperty"]< C6/>scope. $eval (Propertyexrpession, Data[i])}
One. 5 Changes in response data
Most of the time, when we refresh the data, we find that the data on the "bound" to the instruction does not change accordingly. The reason is that most of the time we are "bound" to the data on the scope when the instruction is initialized . when the application runs, and we do not add a listener to the instruction, the data on the instruction does not change with the Model 's data. Let's add the listener.
var function (watchscope) { returnfunction(newval, oldval) { Itemelement.text (newval);})
I > You see, we use scope inside the directive. $watch Listens on a function. Here are a few notable places to note: 1. Using $watch to listen to a function, the function will have a parameter (here, Watchscope ) to express the scope of the listener . 2. Why should we listen to a function, not a value? Because the return of this function is a changed value. 3. When will the changed value change? The answer is when the second parameter data on the $eval function changes (in Angularjs, when a property of the scope changes, it is dependent The function of the is also recalculated. That is, $scope.abc changes, then function Somefun ($scope. ABC) {...} is recalculated again). Because $eval re-operation , the value of its return may change. With the above 3 points, we can bind the instruction in real time , not the data of the binding directive initialization phase .
One. 6 closures
Problems with closures there is not much to say, we should use the " call now Function Expression " (iife) to solve this problem.
for (var i = 0; i < data.length; i++) { (function() {// build iife var index = i; var function (index) { //... } }()) }
Ii. creation of complex directives
-------- Tomorrow Update -------
Resources
"Angularjs Advanced Program Design" P357
directives in the Angularjs