Contrasting the different thinking patterns of jquery and Angularjs

Source: Internet
Author: User

jquery is Dom-driven, ANGULARJS is data-driven, here's an article that explains very well and suggests to look at

This article comes from StackOverflow How does I "Think in AngularJS" if I have a jQuery background? The answer to the highest vote in the question. The answer is more than 3,000 times, and the respondents Josh David Miller are active inOpen Source CommunityDeveloper and co-founder of the Emergenesis company. The answer was originally translated by a number of cloud architects Han Yu and posted on their own blog, and, with the consent of Josh, was recommended by Han Yu to share it with Infoq and posted after the Infoq Community editor Ben Linders review.
1. Do not design the page first, then use the DOM operation to change its presentation
In jquery, you usually design a page and then give it a dynamic effect. This is because jquery is designed to augment the DOM and grow wildly on this simple premise.
But in Angularjs, you muststart from the beginningThink of architecture in the mind. You must start with the features you want to complete, then design the application, and finally design the view instead of "I have such a DOM fragment, I want him to achieve the xxx effect."
2. Don't use Angularjs to strengthen jquery
Similarly, don't start with this mindset: use jquery for x, Y and Z, then just add angularjs models and controllers. This is tempting at first, and that's why I always advise Angularjs novices not to use jquery at all, at least not before they get used to using the "Angular way" development.
I see in the mailing list that many developers use 150 or 200 lines of jquery plugins to create these complex solutions, and then use a bunch of callback functions and $apply to glue it into the ANGULARJS, which looks complicated, but they finally get it done! The problem is that in most cases these jquery plugins can be rewritten with very little Angularjs code, and everything is simple and straightforward to understand.
The bottom line here: When you choose a solution, first "think in AngularJS"; If you can't figure out a solution, go to the community and if there is no simple solution, consider using jquery. But don't let jquery be your crutch, so you can never really master angularjs.
3. Always think in terms of architecture
The first thing to know is that the Single-page app is an app, not a webpage. So apart from thinking like a client developer, we need to be like aServer-SideDevelopers think alike. We must consider how we can split our application into separate, extensible and testable components.
So how do we do that? How do I "Think in AngularJS"? Here are some basic principles, compared to jquery.
View is "Official Record"
In jquery, we programmatically change the view. We will define a drop-down menu as a UL:
<ul class= "Main-menu" >
<li class= "Active" > <a href= "#/home" >Home</a> </li>
<li> <a href= "#/menu1" >menu 1</a>
<ul>
<li><a href= "#/sm1" >submenu 1</a></li>
<li><a href= "#/sm2" >submenu 2</a></li>
<li><a href= "#/sm3" >submenu 3</a></li>
</ul>
</li>
<li> <a href= "#/home" >menu 2</a> </li>
</ul>

In jquery, we will enable this drop-down menu in the application logic:
$ ('. Main-menu '). Dropdownmenu ();

When we focus only on the view, there is no immediate obvious manifestation of any (business) function. For small applications, there's nothing wrong with that. But in larger applications, things can become difficult to understand and difficult to maintain.
In Angularjs, the view is a view-based feature. The UL statement will look like this:
<ul class= "Main-menu" dropdown-menu> ... </ul>

These two ways do the same thing, but in the Angularjs version anyone who sees this template can tell what will happen. Whenever a new member joins the development team, he sees this and knows that there is a directive called Dropdownmenu on the label; he doesn't have to rely on intuition to guess the function of the code or to look at any code. The view itself tells us what's going to happen. It's much clearer.
Developers of first contact with Angularjs often ask the question: How to find all the elements of a certain class and then add a directive to them. But when we told him, "Don't do this, he's always amazed." The reason for not doing this is that it is a half-angularjs way of semi-jquery, and it is not good to do so. The problem here is that developers try to "do JQuery" in a angularjs environment. There will always be some problems in doing so. The view is the official record (translator note: The author may want to express the view as a class citizen). Do not change the DOM outside of a directive. All the directive are applied to the attempt, and the intentions are very clear.
Remember: Don't design, then write tags. You need the architecture and then design.
Data Binding
This is the coolest Angularjs feature so far. This feature makes many of the DOM operations mentioned earlier seem unnecessary. Angularjs will automatically update the view, so you don't have to do it yourself! In jquery, we respond to events and then update the content, just like this:
$.ajax ({
URL: '/myendpoint.json ',
Success:function (data, status) {
$ (' Ul#log '). Append (' <li>data received!</li> ');
}
});

The corresponding view:
<ul class= "Messages" id= "Log" > </ul>

In addition to considering several aspects, we also encounter problems in the previous view. But more importantly, you need to manually reference and update a DOM node. If we want to delete a log entry, we also need to encode the DOM. So how do you test this logic out of the DOM? What if you want to change the presentation?
It's a bit messy and trivial. But in Angularjs, this can be achieved:
$http ('/myendpoint.json '). Then (function (response) {
$scope. Log.push ({
msg: ' Data received! '
});
});

The view looks something like this:
<ul class= "Messages" > <li ng-repeat= "entry in log" ></li> </ul>

But you can actually do this:
<div class= "Messages" > <div class= "alert" ng-repeat= "entry in log" > </div> </div>

Now if we want to use Bootstrap's alert boxes instead of an unordered list, there's no need to change any controller code! More importantly, the view is updated wherever the log is or how it is updated. Automatic. Clever!
Though I didn't show it here,Data Bindingis actually two-way. So these log messages can also be editable in the view. Only need to do this:
<input ng-model= "Entry.msg"/>

。 Simple and happy.
A clear model layer
In jquery, Dom plays a role in the model to some extent. But in Angularjs, we have an independent model layer that can be flexibly managed. Completely independent of the view. This helps the above-mentionedData Binding, maintaining a separation of concerns (independent consideration of views and models), and introducing better testability. This is also mentioned later.
separation of attention points
All of the above is relevant to this vision: Keep yourseparation of attention points。 The view is responsible for showing what is going to happen, model performance data, having a service layer to implement reusable tasks, DOM manipulation and expansion in directive, and using a controller to glue the above things together. This is also described in the other answers, where I only add testabilityDetails in a later paragraph.
Dependency Injection
Dependency InjectionTo help us achieve it.separation of attention points。 If you are from a server language (Java or PHP), you may be familiar with this concept, but if you are a client developer from jquery, this concept may seem a bit silly and superfluous. But it's not really ...
In general, di means that a component can be declared very freely, and then, in another component, it can be obtained only by requesting an instance of that component. No need to know (care) the loading order, or file location, or something like that. This power may not appear immediately, but I only offer one (common: ) Example: Test.
Just say in your application, we need a service that can be implemented through the REST APIServer-SideStorage, and depending on the application state, it is also possible to use (client) local storage. When we run the controller's tests, we don't want to have to interact with the server-after all, it's testing the controller logic. We can just add a mock service,injector with the same name as the service we used to make sure that the controller automatically gets the fake service--controller and doesn't need to know what the difference is.
Speaking of testing ...
4. Always-test-driven development
This is actually the 3rd section on architecture. But it was too important, so I took it out as a top-level paragraph alone.
In all the jquery plugins you've seen, used or written, how many of them have a test set? Not many, because jquery can't withstand the test. But Angularjs can.
In jquery, the only way to test is usually to independently create a component that comes with Sample/demo pages, and then our tests do DOM operations on this page. So we have to develop a component independently and then integrate it into the application. How inconvenient! When using jquery development, too much time, we pick iterations rather than test-driven development. Who can blame us?
But because of the separation of concerns, we can do test-driven development iteratively in Angularjs! For example, want a super simple directive to show our current path. Can be declared in the view:
<a href= "/hello" when-active>hello</a>

OK, now you can write a test:
It (' should add ' active ' when the route changes ', inject (function () {
var elm = $compile (' <a href= "/hello" When-active>hello</a> ') ($scope);
$location. Path ('/not-matching ');
Expect (Elm.hasclass (' active ')). Tobefalsey ();
$location. Path ('/hello ');
Expect (Elm.hasclass (' active ')). Tobetruthy ();
}));

Perform this test to confirm that it is a failure. And then we can start writing about this directive:
. 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 ');
}
});
}
};
});

The test is now passed, and then our menu executes in the requested manner. The development process is both iterative and test-driven. It's so cool.
5. Conceptually, directives is not a packaged jquery
You will often hear "DOM operations only in directive". This is required. Please give it the respect it deserves!
But let's go a little deeper ...
Some directive only decorate what is already in view (think Ngclass) and so sometimes just do the DOM operation and then it's done. But if a directive is like a "widget" and has a template, then it has to be a separation of concerns. In other words, the template itself should be largely independent of its link and controller implementations.
Angularjs has a complete set of tools to make this process very simple; with Ngclass we can dynamically update the Class;ngbind so that we can do two-way data binding. Ngshow and nghide can show and hide an element programmatically, and more-including those we write ourselves. In other words, we can do anything that the DOM operation can achieve. The fewer DOM operations, the easier it is for directive to test, the easier it is to add styles to them, and the easier it will be in the future.Embrace Change, and is more reusable and released.
I've seen a lot of angularjs newbies throw a bunch of jquery into the directive. In other words, they think, "because you can't do DOM in the controller, get that code into directive." It's a good thing to do, but it's still wrong.
Think back to the logger we wrote in the 3rd quarter. Even if we want to put it in a directive, we still want to use the "Angular". It still doesn't have any DOM operations! There are a lot of times when DOM operations are necessary, but it's actually much less than you think! Before doing DOM operations anywhere in the app, ask yourself if you really need to do this. There may be a better way.
Here's an example that shows one of the most common patterns I've ever seen. We want to make a button that can be toggle. (Note: This example is a bit farfetched, verbose, in order to express a more complex case of dealing with problems in the same way.) )
. directive (' mydirective ', function () {
return {
Template: ' <a class= ' btn ' >toggle me!</a> ',
Link:function (scope, element, Attrs) {
var on = false;
$ (Element). Click (function () {
if (ON) {
$ (Element). Removeclass (' active ');
} else {
$ (Element). addclass (' active ');
}
on =!on;
});
}
};
});

Here are some of the wrong places. First of all, Jqeury no need to appear at all. What we're doing here doesn't need jquery!. Second, even if jquery has been used on the page, there is no reason to use it here. Thirdly, even assuming that the directive relies on jquery to work, Jqlite (angular.element) will always use jquery! after loading So we don't need to use the $--with angular.element enough. And the third is closely related, the Jqlite element does not need to be encapsulated--the element that is passed to the link will be a jquery element! Five, we said in the previous paragraph, why do we have to mix the template stuff into logic?
This directive can be (even more complex cases!) ) is easier to write:
. directive (' mydirective ', function () {
return {
Scope:true,
Template: ' <a class= ' btn "ng-class=" {active:on} "ng-click=" Toggle () ">toggle me!</a>",
Link:function (scope, element, Attrs) {
Scope.on = false;
Scope.toggle = function () {
Scope.on =! $scope. On;
};
}
};
});

Once again, the template is in the template, when there are style requirements, you (or your users) can easily replace it, do not have to touch the logic. Re-usability--boom!
Of course there are other benefits, like testing--very simple! Regardless of what is in the template, Directive's internal API is never met, so refactoring is easy. You can change the template arbitrarily without touching the directive. No matter how you change it, the test will always pass.
So if directive is more than just a set of functions like jquery, what are they? Directive is actually an extension of HTML. If HTML doesn't do what you need it to do, you write a directive to do it, and then use it like HTML.
In other words, if the Angularjs library doesn't do something, think about how the development team will do it to match ngclick,ngclass.
Summarize
Don't use jquery. Not even the include. It will keep you at a standstill. If you encounter a problem that you think you already know how to use jquery to solve, before you use $, try to figure out how to fix it under the Angularjs limit. If you don't know, ask! 20 times in 19 times, the best way is not to need jquery. If you try to use jquery, you will increase your workload.
This is my current longest stack overflow answer. In fact, this answer is too long, I have to fill in a captcha. But as I often say: can say more time to say less is actually lazy.
I hope this answer will be useful to you.

Contrasting the different thinking patterns of jquery and Angularjs

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.