Custom instruction learning for a while, learned something on paper, haven't really written a command out of it ... So, with the end of learning, this article in addition to the remaining several parameters, but also to use the combination of various parameters, write a really can use the instructions out to play.
We wrote a simple <say-hello></say-hello> in the custom directive (above), and was able to greet the beautiful woman. But look at the instructions that Ng has built-in, that's how it works: Ng-model= "M", ng-repeat= "A in array", not just as a property, but also assigned to it, bound to a variable in the scope, and the content can be changed dynamically. If our SayHello can be used this way: <say-hello speak= "Content" > Beauty </say-hello> and write what you want to say to a beautiful woman in a variable content, Then as soon as you modify the content value in the controller, the page can show the different words that are said to the beauty. This is more flexible, not to see the beauty will only say a hello, and then there is no then.
To implement such a function, we need to use the scope parameter, as described below.
Use scope for directives to divide scopes
As the name implies, scope is definitely a parameter related to the scope, and its role is to describe the relationship between the instruction and the parent scope, what is this parent scope? Imagine the scenario where we use the instruction, and the page structure should look like this:
<ng-controller= "TESTC"> <speak = "Content"> beauty </say-hello></ Div >
The outer layer will certainly have a controller, which in the definition of controller is basically the same:
var function () {Console.log (' here ')}); App.controller (' TESTC ',function($scope) {$scope. Content = ' It's a nice day today! ‘;});
The parent scope of the so-called SayHello is the scope of the controller named TESTC, and the relationship between the instruction and the parent scope can be as follows:
Take value |
Description |
False |
The default value. Use the parent scope as your own scope |
True |
Create a new scope that inherits the parent scope |
JavaScript objects |
Isolate from the parent scope and specify variables that can be accessed from the parent scope |
At first glance, a value of false and true seems to make no difference, because a value of true inherits the parent scope, that is, any variable in the parent scope can be accessed, and the effect is similar to using the parent scope directly. But there is a difference between the careful thinking, with their own scope can be defined in the inside of their own things, and with the parent scope is mixed with the essence of the difference. It's like a father's money. How much you want to spend, but you make your own money the father can spend as much as it is difficult to say. If you want to see the difference between the two scopes, you can print it out in the link function and remember that the link function can be accessed to scope.
The most useful is to take the third, an object that can be used to explicitly indicate how the property is to be used from the parent scope. When the scope value is an object, we create a scope that is isolated from the parent layer, but not completely isolated, we can manually build a bridge and release some parameters. We have to rely on this to make all kinds of talk to beautiful women. Use them like this:
Scope: { attributeName1: ' Binding_strategy ', attributeName2: ' Binding_strategy ',...}
The key is the property name and the value is the binding policy. Wait a minute! What is a binding strategy? Most hate to take a term but do not explain the behavior! Don't worry, listen to me slowly.
First say the attribute name, do you think this attributeName1 is a variable name in the parent scope? Wrong! In fact, this property name is a name to be used in the directive's own template, and does not correspond to the variables in the parent scope. It's so hard to understand ... It may be too irresponsible to say so, and we'll explain later in the example. Then look at the binding policy, which takes the following rules:
Symbol |
Description |
Example |
@ |
Pass a string as the value of the property. |
STR: ' @string ' |
= |
Binds the data to the directive's properties using a property in the parent scope. |
Name: ' =username ' |
& |
Using a function in the parent scope, you can call the |
GetName: ' &getusername ' |
In short, the symbolic prefix is used to illustrate how to pass a value to the instruction. You can't wait to see an example, let's take a look at the example, waiter, Shangli
Examples Show
I would like to realize the above-mentioned function of speaking with beautiful women, that is, we give the sayhello instruction a property, by assigning values to the property to dynamically change the content of the speech. The main code is as follows:
App.controller (' TESTC ',function($scope) { $scope. Content = ' It's a nice day today! '; }); App.directive (' SayHello ',function() { return { restrict: ' E ', Template: ' <div> Hello,<b ng-transclude></b>,{-{cont}-}</div> ', true, true, Scope: { cont: ' =speak ' } };});
Then in the template, we use the following directives:
<ng-controller= "TESTC"> <speak = "Content"> beauty </say-hello></ Div >
Look at the running effect:
BeautyIn other words
The process of execution is this:
When the ① instruction is compiled, it is scanned into the {{cont}} in the template and found to be an expression;
② finds rules in scope: binds to the parent scope by speak, by passing the attributes in the parent scope;
③speak is bound to the content property in the parent scope and finds its value "It's a nice day today!" ”
④ to display the value of the content in the template
So what we're talking about Cont is bound to the parent scope, and if you dynamically modify the content value of the parent scope, the contents of the page will change, just as you can see by clicking on the word "in other words."
This example is too small for pediatrics! Simple though simple, but can let us understand clearly, in order to test whether you really understand, you can think about how to modify the instruction definition, can let SayHello in the following two ways to use:
<span Say-hello speak= "Content" > Beauty </span>
<span say-hello= "Content" > Beauty </span>
I won't say the answer, it's simple. Here are more important things to do, we agreed to write a really useful thing. Then combine what you learned to write a folding menu, that is, click to expand, and then click on the Shrink back to the menu, (secretly tell you, this example is actually from the desert poor autumn books copied ~).
The Code of the controller and instruction is as follows: (in order to keep the article too long, the code behind me will be folded up, please open it yourself)
app.controller (' TESTC ', function ($scope) {$scope. title = ' personal profile '; $scope. Text = ' Hello everyone, I am a front-end engineer, I am studying ANGULARJS, welcome everyone to communicate with me, email:[email protected] '; }); App.directive (' Expander ', function () {return
{restrict: ' E ', Templateurl: ' expandertemp.html ', replace: true , transclude: true , scope: { MyTitle: ' =etitle '}, Link: function (Scope,element,attris) { Scope.showtext = false ; Scope.toggletext = function () {scope.showtext =! scope.showtext; } } }; });
View Code
The code in the HTML is as follows:
<ScriptID= "expandertemp.html"type= "Text/ng-template"><Div class="Mybox"> <Div class="MyTitle"ng-Click="Toggletext ()">{{MyTitle}}</div> <Div ng-transclude ng-Show="Showtext"></div></div></Script>
Look at the running effect:
It is easier to understand, I only do a little necessary explanation. First we define a template using a definition of NG <script type= "text/ng-template" id= "expandertemp.html"; You can use Templateurl to find the template based on this ID in the instruction. The {-{mytitle}-} expression in the directive is passed from Etitle, specified by the scope parameter, and Etitle points to the title in the parent scope. In order to achieve the click Title to expand the contraction of the content, we put this part of the logic in the link function, the link function can access the scope of the instruction, we define the Showtext property to represent the content part of the explicit, define the Toggletext function to control, and then bind in the template. What if Showtext and toggletext are defined in the controller as a property of $scope? Obviously not, this is the meaning of the isolation scope, and everything in the parent scope is masked except for the title.
In the example above, the scope parameter uses the = sign to specify the property that gets the property's type as the parent scope, and if we want to use the function in the parent scope in the instruction, the & symbol is the same principle.
The above is my understanding of scope, there is an article on the scope of the interpretation of angular more detailed, interested can refer to Http://www.angularjs.cn/A09C.
Use controller and require for inter-instruction communication
It is a good idea to use directives to define a UI component, which is easy to use first, requires only a label or attribute, followed by a high reusability, the controller can dynamically control the content of the UI component, and the ability to have two-way binding. When we want to make the component a little more complex, it is not a command can be done, it requires the collaboration between instructions and instructions to complete, which requires inter-instruction communication.
Think about the principle of our modular development, a module exposed (exports) external interface, another module reference (require) it, you can use the services it provides. This is also the principle of Ng's Inter-instruction collaboration, which is the function of the controller parameters and the require parameter when customizing the instruction.
The controller parameter is used to define the interface provided externally by the directive, which is written as follows:
function controllerconstructor ($scope, $element, $attrs, $transclude)
It is a constructor function that, in the future, constructs an instance to be passed to the instruction that references it. Why call a controller? In fact, you can control me by telling the instructions that reference it. As for what can be controlled, it needs to be defined in the body of the function. First look at the parameters that controller can use, scope, node, node properties, node content migration, which can be passed through dependency injection, so you can write only the parameters you want to use. On how to expose interfaces externally, we illustrate them in the following example.
The Require parameter is used to indicate the other instructions that need to be relied upon, the value of which is a string, the name of the instruction to be relied upon, so that the framework can look for a defined controller from the corresponding instruction according to the name you specify. But it's a little bit special, and to make it easier for the frame to look for, we can add a little prefix to the name: ^, to look for it from the parent node and use it like this: require: ' ^directivename ', if not added, $ The compile service will only be looked up from the node itself. Alternatively, you can use the prefix:? , this prefix will tell the $compile service that if the required controller is not found, do not throw an exception.
What you need to know about this, and then the example time, is still a copy from the book An example, we have to do is an accordion menu, is a number of folding menu together, this example is used to show the communication between the command is more appropriate.
First we need to define a structure for the outer layer, named accordion, with the following code:
App.directive (' accordion ',function(){return{restrict: ' E ', Template: ' <div ng-transclude></div> ', replace:true, transclude:true, Controller:function(){varExpanders = []; This. gotopended =function(Selectedexpander) {Angular.foreach (expanders,function(e) {if(Selectedexpander! = e) {E.showtext =false; } }); } This. Addexpander =function(e) {Expanders.push (e); } } } });
View Code
To explain only the code in the controller, we defined a collapsed menu array expanders, and exposed the interface via the This keyword, providing two methods. Gotopended accepts a selectexpander parameter that modifies the Showtext attribute value of the corresponding expander in the array, enabling explicit control over each submenu. The Addexpander method provides an interface to add elements to the expanders array, so that it can be called to add itself to the accordion in the instruction of the submenu.
Take a look at how our expander needs to be modified:
App.directive (' expander ',function() { return { restrict: ' E ', templateurl: ' Expandertemp.html ', true, true, require: ' ^?accordion ', scope: { title: ' =etitle ' }, function(scope,element,attris,accordioncontroller) { false; Accordioncontroller.addexpander (scope); function () { scope.showtext =! scope.showtext; accordioncontroller.gotopended (scope);}}; });
View Code
First use the Require parameter to introduce the required accordion instruction, add the ^ prefix to indicate the lookup from the parent node and not throw an exception after the failure. You can then use the injected Accordioncontroller in the link function, calling the Addexpander method to pass in its own scope as a parameter for Accordioncontroller to access its properties. Then in the Toggletext method, in addition to the showtext to change their own, but also to call Accordioncontroller Gotopended method to notify the parent instructions to the other menu to shrink up.
Once the instructions are defined, we can use them as follows:
< Accordion > < ng-repeat= "Expander in expanders" etitle= "Expander.title"> {-{expander.text}-}</expander></accordion >
The outer layer uses the accordion instruction, the inner layers use the expander instruction, and the submenu is output on the expander with the Ng-repeat loop. Note that the array expanders traversed here is not the expanders defined in accordion, and if you think so, it is not enough to understand the scope. This expanders is the value of Ng-repeat, which is in the outer controller, so in TESTC we need to add the following data:
$scope. expanders = [ {title: ' Profile ', text: ' Hello, I am a front-end engineer, I am studying ANGULARJS, welcome everyone to communicate with me, email:[email protected] '} , {title: ' My Hobby ', text: ' Sports class: Basketball, football, table tennis. Computer class: Front-end technology, playing DotA. Other classes: Enjoy the Beauty '}, {title: ' Character and Work ', text: ' The quest for perfectionism Virgo Acura man is me ~ serious code cleanliness and 0 tolerance of spam code! Hope that through their own efforts to enter the ideal company work. '} ];
View Code
This is all internationals, try our accordion component is not normal to use it:
After understanding the truth, you can use it handy, I will try to write more complex components in the future practice, this small example will be a good idea ~
Summarize
It's time to sum up, the end of the custom instruction, but I believe the relevant knowledge is certainly far more than that, really want to use the instructions in the project, but also need to understand how the instructions and the other mechanisms of NG interaction, but also need more in-depth understanding of NG's instruction mechanism. Therefore, the transformation of learning and use needs to be tested in practice.
Writing a blog makes My Learning progress is unusually slow, to refuel!
Source: http://www.cnblogs.com/lvdabao/p/3407424.html
Null
Walk into Angularjs (v) custom directive----(bottom)