1. Don't design your page, and then change it with DOM manipulations(1.不要设计您的页面,然后通过DOM操作对其进行更改)
In jQuery, you design a page, and then you make it dynamic.
(在jQuery中,您可以设计一个页面,然后将其动态化。)
This is because jQuery was designed for augmentation and has grown incredibly from that simple premise.(这是因为jQuery是为增强而设计的,并且在此简单前提下得到了难以置信的增长。)
But in AngularJS, you must start from the ground up with your architecture in mind.
(但是在AngularJS中,您必须从头开始,牢记架构。)
Instead of starting by thinking "I have this piece of the DOM and I want to make it do X", you have to start with what you want to accomplish, then go about designing your application, and then finally go about designing your view.(您不必从“我拥有DOM的这个部分,而我想使其成为X”开始,而是必须从要完成的事情开始,然后开始设计应用程序,然后最后开始设计视图。)
2. Don't augment jQuery with AngularJS(2.不要用AngularJS扩充jQuery)
Similarly, don't start with the idea that jQuery does X, Y, and Z, so I'll just add AngularJS on top of that for models and controllers.
(同样,不要以jQuery做X,Y和Z的想法开始,所以我只在模型和控制器的基础上添加AngularJS。)
This is really tempting when you're just starting out, which is why I always recommend that new AngularJS developers don't use jQuery at all, at least until they get used to doing things the "Angular Way".(当您刚入门时,这确实很诱人,这就是为什么我总是建议新的AngularJS开发人员根本不使用jQuery,至少直到他们习惯于“ Angular Way”为止。)
I've seen many developers here and on the mailing list create these elaborate solutions with jQuery plugins of 150 or 200 lines of code that they then glue into AngularJS with a collection of callbacks and $apply
s that are confusing and convoluted;
(我在这里和邮件列表上已经看到很多开发人员使用150或200行代码的jQuery插件创建这些精心设计的解决方案,然后将它们粘贴到AngularJS中,并使用一系列令人困惑和费解的回调和$apply
;)
but they eventually get it working!(但是他们最终使它起作用了!)
The problem is that in most cases that jQuery plugin could be rewritten in AngularJS in a fraction of the code, where suddenly everything becomes comprehensible and straightforward.(问题在于,在大多数情况下,jQuery插件可以用少量代码在AngularJS中重写,从而突然之间所有内容都变得可理解和直接。)
The bottom line is this: when solutioning, first "think in AngularJS";
(底线是:解决时,首先“在AngularJS中思考”;)
if you can't think of a solution, ask the community;(如果您想不出解决方案,请询问社区;)
if after all of that there is no easy solution, then feel free to reach for the jQuery.(如果毕竟,有没有简单的解决方案, 然后随意达到了jQuery。)
But don't let jQuery become a crutch or you'll never master AngularJS.(但是不要让jQuery成为拐杖,否则您将永远无法掌握AngularJS。)
3. Always think in terms of architecture(3.总是从架构上思考)
First know that single-page applications are applications .
(首先知道单页应用程序是application 。)
They're not webpages.(它们不是网页。)
So we need to think like a server-side developer in addition to thinking like a client-side developer.(因此,除了像客户端开发人员那样思考之外 ,我们还需要像服务器端开发人员那样思考。)
We have to think about how to divide our application into individual, extensible, testable components.(我们必须考虑如何将应用程序划分为各个可扩展的可测试组件。)
So then how do you do that?
(那你该怎么做呢?)
How do you "think in AngularJS"?(您如何“在AngularJS中思考”?)
Here are some general principles, contrasted with jQuery.(这里有一些一般性的原则,与jQuery相反。)
The view is the "official record"(该观点是“官方记录”)
In jQuery, we programmatically change the view.
(在jQuery中,我们以编程方式更改视图。)
We could have a dropdown menu defined as a ul
like so:(我们可以将下拉菜单定义为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, in our application logic, we would activate it with something like:
(在jQuery中,在我们的应用程序逻辑中,我们将使用以下方式激活它:)
$('.main-menu').dropdownMenu();
When we just look at the view, it's not immediately obvious that there is any functionality here.
(当我们仅查看视图时,并没有立即发现这里有任何功能。)
For small applications, that's fine.(对于小型应用程序,这很好。)
But for non-trivial applications, things quickly get confusing and hard to maintain.(但是对于非平凡的应用程序,事情很快就会变得混乱并且难以维护。)
In AngularJS, though, the view is the official record of view-based functionality.
(但是,在AngularJS中,视图是基于视图的功能的正式记录。)
Our ul
declaration would look like this instead:(我们的ul
声明看起来像这样:)
<ul class="main-menu" dropdown-menu>
...
</ul>
These two do the same thing, but in the AngularJS version anyone looking at the template knows what's supposed to happen.
(两者的作用相同,但是在AngularJS版本中,任何查看模板的人都知道应该发生什么。)
Whenever a new member of the development team comes on board, she can look at this and then know that there is a directive called dropdownMenu
operating on it;(每当开发团队的新成员加入时,她都可以查看一下,然后知道有一个名为dropdownMenu
的指令正在运行;)
she doesn't need to intuit the right answer or sift through any code.(她不需要输入正确的答案或筛选任何代码。)
The view told us what was supposed to happen.(该视图告诉我们应该发生什么。)
Much cleaner.(清洁得多。)
Developers new to AngularJS often ask a question like: how do I find all links of a specific kind and add a directive onto them.
(刚接触AngularJS的开发人员经常会提出类似的问题:如何找到特定种类的所有链接并向其添加指令。)
The developer is always flabbergasted when we reply: you don't.(当我们回复时,开发人员总是为之震惊:您没有。)
But the reason you don't do that is that this is like half-jQuery, half-AngularJS, and no good.(但是,您不这样做的原因是,这就像是一半的jQuery,一半的AngularJS,而且不好。)
The problem here is that the developer is trying to "do jQuery" in the context of AngularJS.(这里的问题是开发人员试图在AngularJS上下文中“执行jQuery”。)
That's never going to work well.(那永远行不通。)
The view is the official record.(该视图是官方记录。)
Outside of a directive (more on this below), you never, ever, never change the DOM.(在指令之外(请参见下文),您永远不会更改DOM。)
And directives are applied in the view , so intent is clear.(并且在视图中应用了指令,因此意图很明确。)
Remember: don't design, and then mark up.
(记住:不要设计,然后标记。)
You must architect, and then design.(您必须先架构师,然后进行设计。)
Data binding(资料绑定)
This is by far one of the most awesome features of AngularJS and cuts out a lot of the need to do the kinds of DOM manipulations I mentioned in the previous section.
(到目前为止,这是AngularJS最令人敬畏的功能之一,并且消除了我在上一节中提到的进行DOM操作的大量需求。)
AngularJS will automatically update your view so you don't have to!(AngularJS将自动更新您的视图,因此您不必这样做!)
In jQuery, we respond to events and then update content.(在jQuery中,我们响应事件,然后更新内容。)
Something like:(就像是:)
$.ajax({
url: '/myEndpoint.json',
success: function ( data, status ) {
$('ul#log').append('<li>Data Received!</li>');
}
});
For a view that looks like this:
(对于如下所示的视图:)
<ul class="messages" id="log">
</ul>
Apart from mixing concerns, we also have the same problems of signifying intent that I mentioned before.
(除了混合考虑之外,我们还遇到了我之前提到的表示意图的问题。)
But more importantly, we had to manually reference and update a DOM node.(但更重要的是,我们必须手动引用和更新DOM节点。)
And if we want to delete a log entry, we have to code against the DOM for that too.(而且,如果我们要删除日志条目,则也必须针对DOM进行编码。)
How do we test the logic apart from the DOM?(除了DOM,我们如何测试逻辑?)
And what if we want to change the presentation?(如果我们要更改演示文稿怎么办?)
This a little messy and a trifle frail.
(这有点凌乱和脆弱。)
But in AngularJS, we can do this:(但是在AngularJS中,我们可以这样做:)
$http( '/myEndpoint.json' ).then( function ( response ) {
$scope.log.push( { msg: 'Data Received!' } );
});
And our view can look like this:
(我们的视图如下所示:)
<ul class="messages">
<li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>
But for that matter, our view could look like this:
(但就此而言,我们的观点可能是这样的:)
<div class="messages">
<div class="alert" ng-repeat="entry in log">
{{ entry.msg }}
</div>
</div>
And now instead of using an unordered list, we're using Bootstrap alert boxes.
(现在,我们使用了Bootstrap警报框,而不是使用无序列表。)
And we never had to change the controller code!(而且,我们无需更改控制器代码!)
But more importantly, no matter where or how the log gets updated, the view will change too.(但更重要的是,无论在何处或如何更新日志,视图也会改变。)
Automatically.(自动地。)
Neat!(整齐!)
Though I didn't show it here, the data binding is two-way.
(尽管这里没有显示,但数据绑定是双向的。)
So those log messages could also be editable in the view just by doing this: <input ng-model="entry.msg" />
.(因此,只需执行以下操作,即可在视图中编辑这些日志消息: <input ng-model="entry.msg" />
。)
And there was much rejoicing.(有很多的欣喜。)
Distinct model layer(不同的模型层)
In jQuery, the DOM is kind of like the model.
(在jQuery中,DOM有点像模型。)
But in AngularJS, we have a separate model layer that we can manage in any way we want, completely independently from the view.(但是在AngularJS中,我们有一个单独的模型层,我们可以用它想要的任何方式进行管理,完全独立于视图。)
This helps for the above data binding,