This article mainly introduces the differences between jQuery and AngularJS. This article focuses on how a programmer familiar with jQuery can cope with the transformation of some programming ideas in AngularJS, for more information about angularjs, see angularjs. The biggest feeling is that it is completely different from jQuery and various library design concepts based on jQuery, if you cannot recognize this and want to learn angularjs directly for the programmers who have developed jQuery for a long time, you may not know what this thing can be used for or how to use it, how to combine with the UI and other issues, find an article on this aspect on stackoverflow, read it and learn from it. On this basis, I will translate it into Chinese, in order to inspire everyone to learn together.
Original question: If I am familiar with developing client applications using jQuery, how can I get started with angularjs? Can I describe the required mode change? The following questions can help you provide an answer:
1. What are the differences and the biggest differences when designing the client web application?
2. What technologies should I stop using and what technologies should I use as an alternative?
3. Are there any restrictions or restrictions that the server needs to consider?
Answer:
1. Do not design your page first, and then modify it through DOM operations.
In jQuery, you first design a page and then modify its content dynamically. This is because jQuery is designed to expand and greatly add and modify content on this premise, however, in angularjs, you must first design your architecture,
From the very beginning, you have to discard "I have a DOM element and want it to do something" and replace it with "what tasks do I need to complete, and then design your applications, finally, design your view layer ".
2. Do not use angularjs to extend jQuery
Correspondingly, don't let jQuery do something, and then add the angularjs function on this basis to let it manage the idea of model and controller. Therefore, I generally do not recommend AngularJS development beginners to use jQuery at the same time, at least they do not recommend this before they have adapted to AngularJS's development mode. However, when you really begin to adapt to angularjs, you will find that this is a very attractive thing.
I have seen many developers encapsulate jQuery plug-ins with 150-200 lines of code using angularjs callbacks and $ apply methods. This method makes the Code look extremely complex, but they actually ran these plug-ins! The problem is that in most cases, the jQuery plug-in can be rewritten with angularjs, and may only use a small amount of code. At the same time, this rewrite makes the code intuitive and easy to understand, this is obviously too much to encapsulate jQuery Code directly.
Finally, when you encounter a problem, you should first think about it with angularjs. If you cannot find a solution, you can turn to the community. If no one can give a simple solution, so consider using jQuery. Do not make jQuery your crutches. Otherwise, you will never be able to master AngularJS.
3. Focus on the Architecture
First of all, you need to know that single-page applications belong to web applications. They are not traditional multi-page websites. Therefore, we need to think about them as a server and client developer at the same time, we need to think about how to divide our applications into independent, scalable, and testable parts.
Then, how can we use AngularJS thinking to work? The following are some basic principles after comparing them with jQuery:
The following is the view layer of an application:
In jQuery, We dynamically modify this view. We use ul to define a dropdown menu
The Code is as follows:
Home
Menu 1
- Submenu 1
- Submenu 2
- Submenu 3
Menu 2
In jQuery, we use the following logic to use this dropdownMenu
The Code is as follows:
$ ('. Main-menu'). dropdownMenu ();
Let's look back at this view. You will find that its function is not very straightforward. For small applications, this is acceptable, but for large applications, this method will be confusing and difficult to maintain;
In angularjs, this view is actually a view-based function. We can define ul in this way.
The Code is as follows:
The two methods actually do the same thing, but in AngularJS, anyone who sees this view template knows what to do next. Whenever a new member joins the development team, he can see this and find a command called dropdownMenu to operate the view, he doesn't need to guess the correct answer or review other code. This view directly tells us what it is going to do, which is more concise than jQuery.
Some AngularJS beginners often ask this question: how can I find all links of a specific type and add a ve VE on this basis? But when we say, "You shouldn't do this, you are an idea of semi-jQuery and semi-angularjs. "They will be surprised.
The problem is that they are trying to use jQuery to do something in the AngularJS background. This is usually not a good way. You do not need to perform any dom operations outside of the instructions, commands are directly added to the view, so the intention is obvious. Remember, do not design it before modifying it, but first have an architecture and then design it under this framework.
Data Binding
This is the most eye-catching feature of AngularJS so far. In terms of data binding, AngularJS does not support DOM operations, and AngularJS automatically updates views, you don't have to write dom code. In jQuery, we often respond to events and modify views in the following ways:
The Code is as follows:
$. Ajax ({
Url: '/myEndpoint. json ',
Success: function (data, status ){
$ ('Ul # log'). append ('
Data already ed!');
}
});
Compared with such a view
The Code is as follows:
In addition to the Mixed Problems, we also have questions about how to express our intentions. But more importantly, we must manually reference and update this DOM node. If we want to delete one of them, we must operate the DOM element programmatically, in this case, how can we test the logic beyond the DOM node, or we want to change the display mode?
The above code looks messy and fragile, but in AngularJS, we can do this:
The Code is as follows:
$ Http ('/myEndpoint. json'). then (function (response ){
$ Scope. log. push ({msg: 'Data already ed! '});
});
Our view should be like the following
The Code is as follows:
In that case, our view can also be like this.
The Code is as follows:
{Entry. msg }}
Now we do not use ul, but the Bootstrap pop-up box, but we do not need to modify the code in the controller. More importantly, no matter how the data is modified, the view layer will automatically change accordingly, very concise!
Although I will not demonstrate it here, you need to know that data binding is bidirectional. You can edit the data by adding instructions.In addition, there are many other exciting places.
Difference model Layer
In jQuery, DOM is similar to a model, but in AngularJS, we have a model layer different from that in jQuery so that we can manage it in any way we want, it is completely independent from the view. This method helps us to bind data and maintain the focus on separation, and provides better testability.
Separation of concerns
The above is related to this general topic: let you focus on separation, your view layer displays records, and your model layer represents data, you also have a service layer to execute these reusable tasks. You use directive to perform dom operations, expand your view, and connect it to the controller, which is why I have mentioned in other aspects about enhanced testability.
Dependency Injection
Which helps us solve the separation of concerns is dependency injection (DI). If you are a server developer (Java or PHP), you may already be familiar with this concept, however, if you are engaged in client development, you will feel that this concept may be redundant and purely fashionable, but it is not.
In a broad sense, DI means that you can freely declare components and instantiate them from them. You don't have to know the loading sequence, file location, and so on. This magic is not immediately visible, but I will give an example: test.
In the application, we need a service that depends on the application status and local storage to execute server-side storage through a rest API. When we test our controller, we don't have to communicate with the server. After all, we are testing the controller. We only add a mock service that is the same as our original component. The injector ensures that our controller gets a virtual service, and the controller does not have to or need to understand this difference.
Let's talk about testing.
4. Test-driven development
This is the third part of an architecture, but it is so important that I need to put it in the most important position.
In all the jQuery plug-ins we have seen, used, and written, how many have a set of test components? In fact, there are not many, because jQuery is not easy to control in testing, but AngularJS is different from this.
In jQuery, the only way to test is to use a demo page to create an independent component so that our test can perform dom operations. Next, we must develop an independent component and integrate it into our application. This is inconvenient! In many cases, when we use jQuery for development, we actually do a lot of repetitive development instead of test-driven development. Can this blame us?
However, in AngularJS, we can focus on the separation points, so we can do some test-driven development. For example, we have a direve ve to describe our current path in the menu. We can declare it in the view as follows:
The Code is as follows:
Hello
Now, we can write a test to test this nonexistent command when-active.
The Code is as follows:
It ('could add "active" when the route changes', inject (function (){
Var elm = $ compile ('hello') ($ scope );
$ Location. path ('/not-matching ');
Reverse CT (elm. hasClass ('active'). toBeFalsey ();
$ Location. path ('/hello ');
Reverse CT (elm. hasClass ('active'). toBeTruthy ();
}));
Run the test case directly and you will find that it is a failure. In this case, you need to create the command as follows:
The Code is as follows:
. Directive ('whenactive', function ($ location ){
Return {
Scope: true,
Link: function (scope, element, attrs ){
Scope. $ on ('$ routeChangeSuccess', function (){
If ($ location. path () = element. attr ('href ')){
Element. addClass ('active ');
}
Else {
Element. removeClass ('active ');
}
});
}
};
});
Run this test case again, and you will find that the menu is displayed as a request. Our development is both repetitive and testable. It's so cool!
5. In terms of concept, commands are not packaged jQuery
You often hear that dom operations can only be performed in commands. This is required and must be taken seriously.
Let's discuss in depth,
Some commands only describe our views (such as ngClass), so sometimes you can directly operate the dom, but when an instruction is similar to a small object and has its own template, so it should be treated as a separation of focus, that is, its template needs to be separated from the execution logic in the link and other controller functions.
AngularJS has a complete set of tools, which can be easier to separate. Using the ngClass command, we can dynamically update the class. Using ngBind, We can bind two-way data and use ngShow and ngHide.
One element can be displayed and hidden programmatically, and many commands we write. In other words, we can do all the work without Dom operations. The less dom operations, the easier it is to test the instructions. The easier it is to specify their style attributes, the easier it will be to change them in the future, the easier they are to reuse and distribute.
I have seen a lot of new AngularJS users use commands to encapsulate a large string of jQuery code. In other words, since I cannot perform dom operations in the controller, I can put it in the command, although this is much better than the direct dom operation, it is still wrong.
Let's look at the above record. Even if we put it in a command, we still need to operate it in Angular mode. In this way, we do not execute dom operations! In many cases, dom operations are required, but this situation is much less than you think. When we need to perform dom operations, we should first ask ourselves if this is required. This is a better way.
The following is a simple example to show a pattern that I often see. We need a switchable button:
The Code is as follows:
. Directive ('myctive', function (){
Return {
Template: 'toggle me! ',
Link: function (scope, element, attrs ){
Var on = false;
$ (Element). click (function (){
On =! On;
$ (Element). toggleClass ('active', on );
});
}
};
});
In the preceding example, the following error occurs:
1. First of all, jQuery is unnecessary. jQuery is not required for the work here!
2. second, even if we have introduced jquery on the page, we have no reason to use it. We can use angular. element, and our components can run even if jQuery is not introduced in this project.
3. Assume that jquery is needed in our instructions. We can use jqLite to replace jQuery, As long as jquery is introduced, so we do not need to use $ but angular. element;
4. Fourth, it is closely related to the third point. The jqLite element does not need to be wrapped up with $. The element is already a jQuery object passed to the link function;
5. Fifth, we have said before, why not mix our template and logic?
The preceding commands can be rewritten in the following way, even in the most complex situations.
The Code is as follows:
. Directive ('myctive', function (){
Return {
Scope: true,
Template: 'toggle me! ',
Link: function (scope, element, attrs ){
Scope. on = false;
Scope. toggle = function (){
Scope. on =! Scope. on;
};
}
};
});
The template element is in the template attribute. You can easily replace its style, and the logic does not need to be changed at all, so it is completely reused!
There are other advantages. For example, the test is very simple. No matter what is in the template, the instruction API will not change, so refactoring is very simple. You can change your template multiple times without changing the command. No matter how you change it, your test will always pass!
Therefore, commands are not a collection of jQuery code, such as functions, but extensions of HTML code. If HTML code cannot implement the functions you need, you can write an instruction to implement it, then use it like HTML.
In another way, if AngularJS does not do anything else, how can we use the ngClick and ngClass commands?
Summary
Don't always use jquery, or even reference it, it will stop you from moving forward. When we get back to this problem-you know how you solve the problem in AngularJS using jquery, but when you use selectors such as $, you need to think that they are actually banned from AngularJS. If you don't know how to implement them without jQuery, ask someone else and ask them one time, the best way is to avoid using jQuery. Using jQuery will only increase your workload.