AngularJS provides a number of commands to help us operate DOM, process events, bind data, and bind controllers and scopes (ngView. For example, ngClick, ngShow, ngHide, ngRepeat, and many other AngularJS core commands can help us easily use this framework.
Although the built-in commands cover most application scenarios, we often need to create our own commands to simplify operations or reuse components. In this series of articles, I will show you step by step how AngularJS commands work and how to start using/creating them.
In this series of articles, we assume that you already know what commands are and how to use them. If you do not know how to use the command, click here to learn about some basic usage.
Is it difficult to write AngularJS commands?
AngularJS commands may be shocking to those who first came into contact with them. It has many options and some complex features, which is indeed a challenge for the first use. Once you have some knowledge about it, you will find that it is not that bad. When you play a piano or guitar for the first time, you may feel unable to start or be difficult to control, however, after a period of necessary exercises, you will gradually become proficient and even bring up some beautiful songs.
Start custom commands
Why do I need custom commands? If you are executing a task: converting the set of customer data into a specified format and outputting it to a table-you can choose to add the DOM directly, however, this will make testing and control difficult and separate attention. This is a bad implementation in AngularJS, and you certainly do not want to do so. As an alternative, you should customize a command to complete the above operations. On the other hand, you may have some data bindings that appear in different views multiple times and you want to reuse these data bindings. When ngInclude is used to load a subview, the command still works well. Of course, there are still many practical scenarios for commands, which are just superficial.
Let's look at an example of a basic command. Suppose we define the following modules and controllers in the program:
Var app = angular. module ('ctictivesmodule', []);
App. controller ('customer', ['$ scope', function ($ scope ){
Var counter = 0;
$ Scope. customer = {
Name: 'David ',
Street: '1970 Anywhere St .'
};
$ Scope. customers = [
{
Name: 'David ',
Street: '1970 Anywhere St .'
},
{
Name: 'Tina ',
Street: '2017 Crest .'
},
{
Name: 'Michelle ',
Street: '2014 Main St .'
}
];
$ Scope. addCustomer = function (){
Counter ++;
$ Scope. customers. push ({
Name: 'new customer' + counter,
Street: counter + 'Cedar Point St .'
});
};
$ Scope. changeData = function (){
Counter ++;
$ Scope. customer = {
Name: 'James ',
Street: counter + 'Cedar Point St .'
};
};
}]);
For example, we find that we have written a data binding code similar to the following, which appears again and again throughout the program:
Name: {customer. name }}
<Br/>
Street: {customer. street }}
A reuse example is to write this example HTML in a child image (here we name it mychildview.html) and use ngInclude in The Parent View. So that mychildview.html can be reused in the program.
<Div ng-include = "'myChildView.html '"> </div>
Although this can complete the task, it is obvious that another better solution is to write the data binding expression to a custom instruction. To create a command, you must first create a target module to which the command belongs and call the directive () method on the module. The directive () method has a name and a function as the parameter. The following is an example of embedding a data binding expression in a simple command.
Angular. module ('ctictivesmodule ')
. Directive ('mysharedscope ', function (){
Return {
Template: 'Name :{{ customer. Name }}< br/> Street :{{ customer. street }}'
};
});
Does this mean that you can use custom commands to load the child view instead of the ngInclude command? More than that. Commands can accomplish many functions through a few pieces of code, which can simplify the relationship between DOM and business logic. The following is an example of binding the mySharedScope command to a <div> element:
<Div my-shared-scope> </div>
After the command is executed, the following data in the controller is output:
Name: David
Street: 1234 Anywhere St.
Note that the mySharedScope command is referenced in the view by my-shared-scope. Why? In fact, commands are named using the camper method, while commands are referenced using a hyphen. For example, when you use the ngRepeat command, the actual concatenation method is ng-repeat.
Another interesting thing about this instruction is that it always inherits the scope of the view by default ). If you bind the controller (CustomersController) to the view in advance, the customer attribute in the scope is available in the command. This shared scope method works well when you know the parent scope of the instruction, however, when you need to reuse a command, you often cannot understand or control its parent scope. In this case, we can use an independent scope. The specific usage of independent scopes will be detailed in the subsequent articles.
Command attributes
In the above mySharedScope command, we only returned an object literal containing only the template attribute in the function, this attribute is used to define the template for generating HTML commands (in this example, it is a simple binding expression). What other available attributes are there?
Custom commands generally return an object literal to define the attributes required by the command, such as templates, controllers (if needed), DOM operation code, and so on. Some different attributes can be used (you can find the complete attribute list here ). The following are some common key attributes you may encounter, as well as a simple example of using them:
Angular. module ('modulename ')
. Directive ('myctive', function (){
Return {
Restrict: 'EA ', // E = element (element), A = attribute (attribute), C = class (class), M = comment (comment)
Scope :{
// @ Read the property value,
// = Bidirectional data binding,
// & Use functions
Title :'@'},
Template: '<div >{{ myVal }}</div> ',
TemplateUrl: 'mytemplate.html ',
Controller: controllerFunction, // You can embed a custom controller in the command.
Link: function ($ scope, element, attrs) {}// DOM operation
}
});
Some brief descriptions of some attributes are as follows:
Attribute description
Restrict checks the available locations of commands (in the element, attribute, CSS class, or comment)
Scope is used to create a new subscope or independent scope.
Template is used to define the output content of a command. It can contain HTML, data binding expressions, and even other commands.
TemplateUrl provides the path of a template used by the command, or the ID of a template defined by the <script> label.
The controller is used to define a controller to contact the View template.
Link is mainly used to process some DOM operations.
Operate DOM
In addition to binding data to a template, commands can also be used to operate the DOM. This uses the link function mentioned above.
The link function usually receives three parameters (in some cases, there are other parameters), including the current scope, DOM elements associated with the instruction, and attributes bound to the element. The following is an example of how to use commands to process clicks, mouse moves, and mouse moves:
App. directive ('mydomainve VE', function (){
Return {
Link: function ($ scope, element, attrs ){
Element. bind ('click', function (){
Element.html ('You clicked me! ');
});
Element. bind ('mouseenter', function (){
Element.css ('background-color', 'yellow ');
});
Element. bind ('mouseleave ', function (){
Element.css ('background-color', 'white ');
});
}
};
});
To use this command, you need to add the following code to your view:
<Div my-dom-directive> Click Me! </Div>
When the mouse moves in or out, the background color of <div> will be yellow and white (although inline style is used in this example, it will be better to use CSS class ). When the target element is clicked, the internal HTML will become "You clicked me !". Commands are the only service in AngularJS that can directly operate the DOM. Learning to use them will be helpful for your learning and usage.
Format AngularJS command code
Although mySharedScope and myDomDirective commands run well, I prefer to use some specific formats when defining commands and other AngularJS components, as shown below:
(Function (){
Var directive = function (){
Return {
};
};
Angular. module ('modulename ')
. Directive ('ctivenvename', directive );
}());
This code uses an self-executed function to enclose all the logic code to prevent global namespace contamination. Use the directive variable to define the directive function. Finally, call the directive () function on the module and pass the directive variable. There are many techniques that can be used to format code, but I prefer the above.
Summary
This is the first article in this series. You can learn some basic instruction knowledge and how to create a simple instruction. This is just the surface! In the next article, we will discuss independent scopes and different data binding methods.