Mar*_*cok 4518 javascript jquery angularjs
假设我熟悉在jQuery中开发客户端应用程序,但现在我想开始使用AngularJS.你能描述一下必要的范式转变吗?以下是一些可能有助于您确定答案的问题:
我不是在寻找jQuery
和之间的详细比较AngularJS
.
Jos*_*ler 7180
在jQuery中,您设计了一个页面,然后将其设置为动态.这是因为jQuery是为增强而设计的,并且从这个简单的前提中获得了令人难以置信的增长.
但是在AngularJS中,您必须从头开始考虑您的架构.我不是首先考虑"我有这块DOM而我想让它做X",而是从你想要完成的事情开始,然后去设计你的应用程序,然后最后去设计你的视图.
同样,不要从jQuery做X,Y和Z的想法开始,所以我只是在模型和控制器的基础上添加AngularJS.这是真的很诱人,当你刚刚起步的,这就是为什么我总是建议新AngularJS开发商不使用jQuery可言,至少直到他们习惯做的事情"角之路".
我在这里和邮件列表上看到很多开发人员使用150或200行代码的jQuery插件创建这些精心设计的解决方案,然后他们将这些代码粘合到AngularJS中,其中包含一系列$apply
令人困惑和错综复杂的回调.但他们最终得到它的工作!问题是,在大多数情况下,jQuery插件可以在AngularJS中以一小部分代码重写,突然之间一切都变得易于理解和直接.
最重要的是:解决问题时,首先要"在AngularJS中思考"; 如果你想不出解决方案,请向社区提问; 如果完全没有简单的解决方案,那么随时可以找到jQuery.但是不要让jQuery成为拐杖或者你永远不会掌握AngularJS.
首先要知道单页应用程序是应用程序.他们不是网页.因此,我们需要这样想一个服务器端的开发者除了想着像客户端开发.我们必须考虑如何将我们的应用程序划分为单独的,可扩展的,可测试的组件.
那么接下来怎么做呢?你如何"在AngularJS中思考"?以下是一些与jQuery形成对比的一般原则.
在jQuery中,我们以编程方式更改视图.我们可以将下拉菜单定义为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>
Run Code Online (Sandbox Code Playgroud)
在jQuery中,在我们的应用程序逻辑中,我们将使用以下内容激活它:
$('.main-menu').dropdownMenu();
Run Code Online (Sandbox Code Playgroud)
当我们只看这个视图时,这里没有任何功能并不是很明显.对于小型应用,这很好.但对于非平凡的应用程序,事情很快就会变得混乱和难以维护.
但是,在AngularJS中,视图是基于视图的功能的官方记录.我们的ul
声明将是这样的:
<ul class="main-menu" dropdown-menu>
...
</ul>
Run Code Online (Sandbox Code Playgroud)
这两个做同样的事情,但在AngularJS版本中,任何看模板的人都知道应该发生什么.每当开发团队的新成员加入时,她都可以看看这个,然后知道有一个叫做dropdownMenu
操作的指令; 她不需要直截了当地回答正确的答案或筛选任何代码.该观点告诉我们应该发生什么.更清洁.
AngularJS的新手开发人员经常会问一个问题:如何查找特定类型的所有链接并在其上添加指令.当我们回复时,开发人员总是大惊小怪:你没有.但你不这样做的原因是,这就像半jQuery,半AngularJS,并没有好处.这里的问题是开发人员试图在AngularJS的上下文中"执行jQuery".那永远不会好起来的.该观点是官方记录.在指令之外(以下更多内容),您永远不会永远不会更改DOM.并且指令在视图中应用,因此意图很明确.
记住:不要设计,然后标记.你必须设计,然后设计.
这是迄今为止AngularJS最强大的功能之一,并且切除了我在上一节中提到的做各种DOM操作的需要.AngularJS会自动更新您的视图,所以您不必!在jQuery中,我们响应事件然后更新内容.就像是:
$.ajax({
url: '/myEndpoint.json',
success: function ( data, status ) {
$('ul#log').append('<li>Data Received!</li>');
}
});
Run Code Online (Sandbox Code Playgroud)
对于看起来像这样的视图:
<ul class="messages" id="log">
</ul>
Run Code Online (Sandbox Code Playgroud)
除了混合问题,我们也有同样的问题,表明我之前提到的意图.但更重要的是,我们必须手动引用和更新DOM节点.如果我们想要删除日志条目,我们也必须针对DOM进行编码.我们如何测试除DOM之外的逻辑?如果我们想改变演示文稿怎么办?
这有点凌乱,有点脆弱.但在AngularJS中,我们可以这样做:
$http( '/myEndpoint.json' ).then( function ( response ) {
$scope.log.push( { msg: 'Data Received!' } );
});
Run Code Online (Sandbox Code Playgroud)
我们的观点可能如下所示:
<ul class="messages">
<li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
但就此而言,我们的观点可能如下所示:
<div class="messages">
<div class="alert" ng-repeat="entry in log">
{{ entry.msg }}
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
而现在我们使用的是Bootstrap警报框,而不是使用无序列表.我们永远不必更改控制器代码!但更重要的是,无论日志在何处或如何更新,视图也会发生变化.自动.整齐!
虽然我没有在这里展示,但数据绑定是双向的.所以这些日志消息也可以通过这样做在视图中编辑:<input ng-model="entry.msg" />
.有很多的欣喜.
在jQuery中,DOM有点像模型.但是在AngularJS中,我们有一个单独的模型层,我们可以以任何方式管理,完全独立于视图.这有助于上述数据绑定,保持关注点分离,并引入更大的可测试性.其他答案提到了这一点,所以我就把它留在那里.
以上所有内容都与这个主题相关:将您的担忧分开.你的观点作为应该发生的事情的官方记录(大多数情况下); 你的模型代表你的数据; 你有一个服务层来执行可重用的任务; 你做DOM操作并用指令扩充你的视图; 然后将它们与控制器粘合在一起.在其他答案中也提到了这一点,我要添加的唯一内容与可测试性有关,我将在下面的另一部分中讨论.
为了帮助我们分离关注点,依赖注入(DI).如果你来自服务器端语言(从Java到PHP),你可能已经熟悉了这个概念,但如果你是一个来自jQuery的客户端人,这个概念可能看起来从愚蠢到多余到时髦.但事实并非如此.:-)
从广义的角度来看,DI意味着您可以非常自由地声明组件,然后从任何其他组件声明组件,只需要求它的实例,它就会被授予.您无需了解加载顺序,文件位置或类似内容.电源可能不会立即可见,但我只提供一个(常见)示例:测试.
让我们说在我们的应用程序中,我们需要一个通过REST API 实现服务器端存储的服务,并且根据应用程序状态,还需要本地存储.在我们的控制器上运行测试时,我们不希望必须与服务器通信 - 毕竟我们正在测试控制器.我们可以添加一个与原始组件同名的模拟服务,注入器将确保我们的控制器自动获取假的 - 我们的控制器不会,也不需要知道差异.
说到测试......
这实际上是关于体系结构的第3部分的一部分,但是我将它作为自己的顶级部分非常重要.
在您看过,使用过或编写的所有jQuery插件中,有多少有一个附带的测试套件?不是很多,因为jQuery不太适合.但AngularJS是.
在jQuery中,唯一的测试方法通常是使用示例/演示页面独立创建组件,我们的测试可以对其执行DOM操作.那么我们必须单独开发一个组件,然后将其集成到我们的应用程序中.多么不方便!在大多数情况下,在使用jQuery进行开发时,我们选择迭代而不是测试驱动开发.谁可以怪我们?
但是因为我们有关注点分离,我们可以在AngularJS中迭代地进行测试驱动开发!例如,假设我们想要一个超级简单的指令在我们的菜单中指出我们当前的路线是什么.我们可以在应用程序视图中声明我们想要的内容:
<a href="/hello" when-active>Hello</a>
Run Code Online (Sandbox Code Playgroud)
好的,现在我们可以为不存在的when-active
指令编写一个测试:
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();
}));
Run Code Online (Sandbox Code Playgroud)
当我们运行测试时,我们可以确认它失败了.只有现在我们才能创建我们的指令:
.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 Code Online (Sandbox Code Playgroud)
我们的测试现在通过,我们的菜单按要求执行.我们的开发既是迭代的,也是测试驱动的.妖兽爽.
您经常会听到"只在指令中执行DOM操作".这是必要的.善意对待它!
但是让我们深入一点......
一些指令只是装饰视图中的内容(想想ngClass
),因此有时会直接进行DOM操作,然后基本完成.但是,如果指令就像一个"小部件"并且有一个模板,那么它也应该尊重关注点的分离.也就是说,模板也应该在很大程度上独立于链接和控制器功能中的实现.
AngularJS附带了一整套工具,使这一切变得非常简单; 与ngClass
我们可以动态更新的类; ngModel
允许双向数据绑定; ngShow
并以ngHide
编程方式显示或隐藏元素; 还有更多 - 包括我们自己写的那些.换句话说,我们可以在没有 DOM操作的情况下做各种各样的超棒.DOM操作越少,测试指令就越容易,它们的样式就越容易,将来它们就越容易改变,它们的可重用性和可分发性就越高.
我看到许多开发人员使用指令作为抛出一堆jQuery的地方的AngularJS的新手.换句话说,他们认为"因为我不能在控制器中进行DOM操作,所以我将把代码放在指令中".虽然这确实好得多,但它通常仍然是错误的.
想想我们在第3节中编写的记录器.即使我们将其放在指令中,我们仍然希望将其作为"Angular Way".它仍然不需要任何DOM操作!有很多时候需要DOM操作,但它比你想象的要少得多!在应用程序中的任何位置进行DOM操作之前,请问自己是否真的需要.可能有更好的方法.
这是一个快速示例,显示了我最常见的模式.我们想要一个可切换的按钮.(注意:这个例子有点人为,并且表示更复杂的案例,以完全相同的方式解决.)
.directive( 'myDirective', function () {
return {
template: '<a class="btn">Toggle me!</a>',
link: function ( scope, element, attrs ) {
var on = false;
$(element).click( function () {
on = !on;
$(element).toggleClass('active', on);
});
}
};
});
Run Code Online (Sandbox Code Playgroud)
这有一些问题:
angular.element
,当放入没有jQuery的项目时,我们的组件仍然可以工作.angular.element
)将始终使用jQuery,如果它是装的!所以我们不需要使用$
- 我们可以使用angular.element
.$
- element
传递给link
函数的元素已经是 jQuery元素了!这个指令可以被重写(即使对于非常复杂的情况!)更简单如下:
.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;
};
}
};
});
Run Code Online (Sandbox Code Playgroud)
同样,模板内容在模板中,因此您(或您的用户)可以轻松地将其交换为满足任何必要样式的模板,并且逻辑永远不必被触及.可重用性 - 热潮!
还有其他所有好处,比如测试 - 这很容易!无论模板中有什么内容,都不会触及指令的内部API,因此重构很容易.您可以根据需要更改模板,而无需触及指令.无论你改变什么,你的测试仍然通过.
w00t!
因此,如果指令不仅仅是类jQuery函数的集合,它们是什么?指令实际上是HTML的扩展.如果HTML不需要它做某事,你可以编写一个指令来为你完成,然后就像使用它一样使用它.
换句话说,如果AngularJS没做什么开箱,认为球队如何完成它与合身的时候ngClick
,ngClass
等.
甚至不使用jQuery.甚至不包括它.它会阻止你.当你遇到一个问题,你认为你已经知道如何在jQuery中解决,在你达到之前$
,试着考虑如何在AngularJS的范围内做到这一点.如果你不知道,请问!20次中有19次,最好的方法是不需要jQuery并尝试使用jQuery解决它,为您提供更多的工作.
Mar*_*cok 407
在jQuery中,选择器用于查找DOM元素,然后将事件处理程序绑定/注册到它们.当事件触发时,执行(命令性)代码以更新/更改DOM.
在AngularJS中,您需要考虑视图而不是DOM元素.视图是包含AngularJS 指令的(声明性)HTML .指令为我们幕后设置了事件处理程序,并为我们提供了动态数据绑定.选择器很少使用,因此对ID(以及某些类型的类)的需求大大减少.视图与模型相关联(通过范围).视图是模型的投影.事件更改模型(即数据,范围属性)以及投影这些模型的视图会"自动"更新.
在AngularJS中,考虑模型,而不是jQuery选择的DOM元素来保存您的数据.将视图视为这些模型的投影,而不是注册回调来操纵用户看到的内容.
jQuery使用不引人注目的JavaScript - 行为(JavaScript)与结构(HTML)分离.
AngularJS使用控制器和指令(每个控制器和指令可以有自己的控制器和/或编译和链接函数)来从视图/结构(HTML)中删除行为.Angular还提供服务和过滤器,以帮助分离/组织您的应用程序.
设计AngularJS应用程序的一种方法:
你可以在不知道JavaScript原型继承如何工作的情况下使用jQuery做很多事情.在开发AngularJS应用程序时,如果您对JavaScript继承有很好的理解,就可以避免一些常见的陷阱.推荐阅读:AngularJS中范围原型/原型继承的细微差别是什么?
sup*_*ary 184
AngularJS和jQuery采用了截然不同的意识形态.如果您来自jQuery,您可能会发现一些令人惊讶的差异.Angular可能会让你生气.
这是正常的,你应该推进.Angular值得.
jQuery为您提供了一个工具包,用于选择DOM的任意位并对其进行临时更改.你几乎可以做任何你喜欢的事情.
相反,AngularJS为您提供了一个编译器.
What this means is that AngularJS reads your entire DOM from top to bottom and treats it as code, literally as instructions to the compiler. As it traverses the DOM, It looks for specific directives (compiler directives) that tell the AngularJS compiler how to behave and what to do. Directives are little objects full of JavaScript which can match against attributes, tags, classes or even comments.
When the Angular compiler determines that a piece of the DOM matches a particular directive, it calls the directive function, passing it the DOM element, any attributes, the current $scope (which is a local variable store), and some other useful bits. These attributes may contain expressions which can be interpreted by the Directive, and which tell it how to render, and when it should redraw itself.
Directives can then in turn pull in additional Angular components such as controllers, services, etc. What comes out the bottom of the compiler is a fully formed web application, wired up and ready to go.
This means that Angular is Template Driven. Your template drives the JavaScript, not the other way around. This is a radical reversal of roles, and the complete opposite of the unobtrusive JavaScript we have been writing for the last 10 years or so. This can take some getting used to.
If this sounds like it might be over-prescriptive and limiting, nothing could be farther from the truth. Because AngularJS treats your HTML as code, you get HTML level granularity in your web application. Everything is possible, and most things are surprisingly easy once you make a few conceptual leaps.
Let's get down to the nitty gritty.
Angular and jQuery do different things. AngularJS gives you a set of tools to produce web applications. jQuery mainly gives you tools for modifying the DOM. If jQuery is present on your page, AngularJS will use it automatically. If it isn't, AngularJS ships with jQuery Lite, which is a cut down, but still perfectly usable version of jQuery.
Misko likes jQuery and doesn't object to you using it. However you will find as you advance that you can get a pretty much all of your work done using a combination of scope, templates and directives, and you should prefer this workflow where possible because your code will be more discrete, more configurable, and more Angular.
如果你使用jQuery,你不应该把它洒到这个地方.AngularJS中DOM操作的正确位置是在一个指令中.稍后会详细介绍.
jQuery通常不引人注意地应用.您的JavaScript代码链接在标题(或页脚)中,这是它唯一提到的地方.我们使用选择器来挑选页面的位并编写插件来修改这些部分.
JavaScript处于控制之中.HTML具有完全独立的存在.即使没有JavaScript,您的HTML仍然是语义.Onclick属性是非常糟糕的做法.
One of the first things your will notice about AngularJS is that custom attributes are everywhere. Your HTML will be littered with ng attributes, which are essentially onClick attributes on steroids. These are directives (compiler directives), and are one of the main ways in which the template is hooked to the model.
When you first see this you might be tempted to write AngularJS off as old school intrusive JavaScript (like I did at first). In fact, AngularJS does not play by those rules. In AngularJS, your HTML5 is a template. It is compiled by AngularJS to produce your web page.
This is the first big difference. To jQuery, your web page is a DOM to be manipulated. To AngularJS, your HTML is code to be compiled. AngularJS reads in your whole web page and literally compiles it into a new web page using its built in compiler.
Your template should be declarative; its meaning should be clear simply by reading it. We use custom attributes with meaningful names. We make up new HTML elements, again with meaningful names. A designer with minimal HTML knowledge and no coding skill can read your AngularJS template and understand what it is doing. He or she can make modifications. This is the Angular way.
在开始使用AngularJS并运行教程时,我问自己的第一个问题是"我的代码在哪里?" .我没有写过JavaScript,但我有这些行为.答案很明显.因为AngularJS编译DOM,所以AngularJS将您的HTML视为代码.对于许多简单的情况,只需编写一个模板就可以了,让AngularJS将它编译成一个应用程序.
您的模板可以驱动您的应用 它被视为DSL.您编写AngularJS组件,AngularJS将负责将它们拉入并根据模板的结构在适当的时间提供它们.这与标准MVC模式非常不同,其中模板仅用于输出.
It's more similar to XSLT than Ruby on Rails for example.
This is a radical inversion of control that takes some getting used to.
Stop trying to drive your application from your JavaScript. Let the template drive the application, and let AngularJS take care of wiring the components together. This also is the Angular way.
With jQuery your HTML page should contain semantic meaningful content. If the JavaScript is turned off (by a user or search engine) your content remains accessible.
Because AngularJS treats your HTML page as a template. The template is not supposed to be semantic as your content is typically stored in your model which ultimately comes from your API. AngularJS compiles your DOM with the model to produce a semantic web page.
Your HTML source is no longer semantic, instead, your API and compiled DOM are semantic.
In AngularJS, meaning lives in the model, the HTML is just a template, for display only.
At this point you likely have all sorts of questions concerning SEO and accessibility, and rightly so. There are open issues here. Most screen readers will now parse JavaScript. Search engines can also index AJAXed content. Nevertheless, you will want to make sure you are using pushstate URLs and you have a decent sitemap. See here for a discussion of the issue: /sf/answers/1627176561/
Separation of concerns (SOC) is a pattern that grew up over many years of web development for a variety of reasons including SEO, accessibility and browser incompatibility. It looks like this:
Again, AngularJS does not play by their rules. In a stroke, AngularJS does away with a decade of received wisdom and instead implements an MVC pattern in which the template is no longer semantic, not even a little bit.
It looks like this:
MVC and SOC are not on opposite ends of the same scale, they are on completely different axes. SOC makes no sense in an AngularJS context. You have to forget it and move on.
If, like me, you lived through the browser wars, you might find this idea quite offensive. Get over it, it'll be worth it, I promise.
Plugins extend jQuery. AngularJS Directives extend the capabilities of your browser.
In jQuery we define plugins by adding functions to the jQuery.prototype. We then hook these into the DOM by selecting elements and calling the plugin on the result. The idea is to extend the capabilities of jQuery.
For example, if you want a carousel on your page, you might define an unordered list of figures, perhaps wrapped in a nav element. You might then write some jQuery to select the list on the page and restyle it as a gallery with timeouts to do the sliding animation.
In AngularJS, we define directives. A directive is a function which returns a JSON object. This object tells AngularJS what DOM elements to look for, and what changes to make to them. Directives are hooked in to the template using either attributes or elements, which you invent. The idea is to extend the capabilities of HTML with new attributes and elements.
The AngularJS way is to extend the capabilities of native looking HTML. You should write HTML that looks like HTML, extended with custom attributes and elements.
If you want a carousel, just use a <carousel />
element, then define a directive to pull in a template, and make that sucker work.
The tendency with jQuery is to write great big plugins like lightbox which we then configure by passing in numerous values and options.
This is a mistake in AngularJS.
Take the example of a dropdown. When writing a dropdown plugin you might be tempted to code in click handlers, perhaps a function to add in a chevron which is either up or down, perhaps change the class of the unfolded element, show hide the menu, all helpful stuff.
Until you want to make a small change.
Say you have a menu that you want to unfold on hover. Well now we have a problem. Our plugin has wired in our click handler for us, we're going to need to add a configuration option to make it behave differently in this specific case.
In AngularJS we write smaller directives. Our dropdown directive would be ridiculously small. It might maintain the folded state, and provide methods to fold(), unfold() or toggle(). These methods would simply update $scope.menu.visible which is a boolean holding the state.
Now in our template we can wire this up:
<a ng-click="toggle()">Menu</a>
<ul ng-show="menu.visible">
...
</ul>
Run Code Online (Sandbox Code Playgroud)
Need to update on mouseover?
<a ng-mouseenter="unfold()" ng-mouseleave="fold()">Menu</a>
<ul ng-show="menu.visible">
...
</ul>
Run Code Online (Sandbox Code Playgroud)
The template drives the application so we get HTML level granularity. If we want to make case by case exceptions, the template makes this easy.
JQuery plugins are created in a closure. Privacy is maintained within that closure. It's up to you to maintain your scope chain within that closure. You only really have access to the set of DOM nodes passed in to the plugin by jQuery, plus any local variables defined in the closure and any globals you have defined. This means that plugins are quite self contained. This is a good thing, but can get restrictive when creating a whole application. Trying to pass data between sections of a dynamic page becomes a chore.
AngularJS has $scope objects. These are special objects created and maintained by AngularJS in which you store your model. Certain directives will spawn a new $scope, which by default inherits from its wrapping $scope using JavaScript prototypical inheritance. The $scope object is accessible in the controller and the view.
This is the clever part. Because the structure of $scope inheritance roughly follows the structure of the DOM, elements have access to their own scope, and any containing scopes seamlessly, all the way up to the global $scope (which is not the same as the global scope).
This makes it much easier to pass data around, and to store data at an appropriate level. If a dropdown is unfolded, only the dropdown $scope needs to know about it. If the user updates their preferences, you might want to update the global $scope, and any nested scopes listening to the user preferences would automatically be alerted.
This might sound complicated, in fact, once you relax into it, it's like flying. You don't need to create the $scope object, AngularJS instantiates and configures it for you, correctly and appropriately based on your template hierarchy. AngularJS then makes it available to your component using the magic of dependency injection (more on this later).
In jQuery you make all your DOM changes by hand. You construct new DOM elements programatically. If you have a JSON array and you want to put it to the DOM, you must write a function to generate the HTML and insert it.
In AngularJS you can do this too, but you are encouraged to make use of data binding. Change your model, and because the DOM is bound to it via a template your DOM will automatically update, no intervention required.
Because data binding is done from the template, using either an attribute or the curly brace syntax, it's super easy to do. There's little cognitive overhead associated with it so you'll find yourself doing it all the time.
<input ng-model="user.name" />
Run Code Online (Sandbox Code Playgroud)
Binds the input element to $scope.user.name
. Updating the input will update the value in your current scope, and vice-versa.
Likewise:
<p>
{{user.name}}
</p>
Run Code Online (Sandbox Code Playgroud)
will output the user name in a paragraph. It's a live binding, so if the $scope.user.name
value is updated, the template will update too.
In jQuery making an Ajax call is fairly simple, but it's still something you might think twice about. There's the added complexity to think about, and a fair chunk of script to maintain.
In AngularJS, Ajax is your default go-to solution and it happens all the time, almost without you noticing. You can include templates with ng-include. You can apply a template with the simplest custom directive. You can wrap an Ajax call in a service and create yourself a GitHub service, or a Flickr service, which you can access with astonishing ease.
In jQuery, if we want to accomplish a small non-dom related task such as pulling a feed from an API, we might write a little function to do that in our closure. That's a valid solution, but what if we want to access that feed often? What if we want to reuse that code in another application?
AngularJS gives us service objects.
Services are simple objects that contain functions and data. They are always singletons, meaning there can never be more than one of them. Say we want to access the Stack Overflow API, we might write a StackOverflowService
which defines methods for doing so.
Let's say we have a shopping cart. We might define a ShoppingCartService which maintains our cart and contains methods for adding and removing items. Because the service is a singleton, and is shared by all other components, any object that needs to can write to the shopping cart and pull data from it. It's always the same cart.
Service objects are self-contained AngularJS components which we can use and reuse as we see fit. They are simple JSON objects containing functions and Data. They are always singletons, so if you store data on a service in one place, you can get that data out somewhere else just by requesting the same service.
AngularJS manages your dependencies for you. If you want an object, simply refer to it and AngularJS will get it for you.
Until you start to use this, it's hard to explain just what a massive time boon this is. Nothing like AngularJS DI exists inside jQuery.
DI means that instead of writing your application and wiring it together, you instead define a library of components, each identified by a string.
Say I have a component called 'FlickrService' which defines methods for pulling JSON feeds from Flickr. Now, if I want to write a controller that can access Flickr, I just need to refer to the 'FlickrService' by name when I declare the controller. AngularJS will take care of instantiating the component and making it available to my controller.
For example, here I define a service:
myApp.service('FlickrService', function() {
return {
getFeed: function() { // do something here }
}
});
Run Code Online (Sandbox Code Playgroud)
Now when I want to use that service I just refer to it by name like this:
myApp.controller('myController', ['FlickrService', function(FlickrService) {
FlickrService.getFeed()
}]);
Run Code Online (Sandbox Code Playgroud)
AngularJS will recognise that a FlickrService object is needed to instantiate the controller, and will provide one for us.
This makes wiring things together very easy, and pretty much eliminates any tendency towards spagettification. We have a flat list of components, and AngularJS hands them to us one by one as and when we need them.
jQuery says very little about how you should organise your code. AngularJS has opinions.
AngularJS gives you modules into which you can place your code. If you're writing a script that talks to Flickr for example, you might want to create a Flickr module to wrap all your Flickr related functions in. Modules can include other modules (DI). Your main application is usually a module, and this should include all the other modules your application will depend on.
You get simple code reuse, if you want to write another application based on Flickr, you can just include the Flickr module and voila, you have access to all your Flickr related functions in your new application.
Modules contain AngularJS components. When we include a module, all the components in that module become available to us as a simple list identified by their unique strings. We can then inject those components into each other using AngularJS's dependency injection mechanism.
AngularJS and jQuery are not enemies. It's possible to use jQuery within AngularJS very nicely. If you're using AngularJS well (templates, data-binding, $scope, directives, etc.) you will find you need a lot less jQuery than you might otherwise require.
The main thing to realise is that your template drives your application. Stop trying to write big plugins that do everything. Instead write little directives that do one thing, then write a simple template to wire them together.
Think less about unobtrusive JavaScript, and instead think in terms of HTML extensions.
I got so excited about AngularJS, I wrote a short book on it which you're very welcome to read online http://nicholasjohnson.com/angular-book/. I hope it's helpful.
Uli*_*ses 152
你能描述一下必要的范式转变吗?
势在必行与陈述
使用jQuery,您可以一步一步地告诉DOM需要发生什么.使用AngularJS,您可以描述所需的结果,但不能描述如何执行此操作.更多关于这里.另外,请查看Mark Rajcok的答案.
如何以不同方式构建和设计客户端Web应用程序?
AngularJS是一个使用MVC模式的整个客户端框架(查看它们的图形表示).它非常注重关注点的分离.
最大的区别是什么?我应该停止做什么/使用什么; 我应该开始做什么/使用呢?
jQuery是一个库
AngularJS是一个漂亮的客户端框架,高度可测试,它结合了许多很酷的东西,如MVC,依赖注入,数据绑定等等.
它侧重于关注点和测试(单元测试和端到端测试)的分离,这有助于测试驱动的开发.
最好的方法是通过他们的精彩教程.你可以在几个小时内完成这些步骤; 但是,如果你想掌握幕后的概念,它们包含了无数的参考资料以供进一步阅读.
是否存在任何服务器端注意事项/限制?
您可以在已经使用纯jQuery的现有应用程序上使用它.但是,如果要充分利用AngularJS功能,可以考虑使用RESTful方法对服务器端进行编码.
这样做将允许您利用他们的资源工厂,它创建服务器端RESTful API的抽象,并使服务器端调用(获取,保存,删除等)非常容易.
Sco*_*pey 84
为了描述"范式转换",我认为一个简短的回答就足够了.
在jQuery中,您通常使用选择器来查找元素,然后将它们连接起来:
$('#id .class').click(doStuff);
在AngularJS中,您可以使用指令直接标记元素,以便将它们连接起来:
<a ng-click="doStuff()">
AngularJS并不需要(或希望)你找到使用选择元素- AngularJS的之间的主要区别jqLite与全面的jQuery的是jqLite不支持选择.
所以当人们说"根本不包含jQuery"时,主要是因为他们不希望你使用选择器; 他们希望你学习使用指令.直接,不选择!
Nic*_*ing 69
jQuery制作了一些可笑的长命令,比如getElementByHerpDerp
简短和跨浏览器.
AngularJS允许您创建自己的HTML标记/属性,这些标记/属性可以很好地处理动态Web应用程序(因为HTML是为静态页面设计的).
说"我有一个jQuery背景我如何在AngularJS中思考?" 就像说"我有一个HTML背景我怎么用JavaScript思考?" 你提问的事实表明你很可能不理解这两种资源的根本目的.这就是为什么我选择通过简单地指出基本区别来回答问题,而不是通过列表说"AngularJS使用指令而jQuery使用CSS选择器来创建一个jQuery对象来执行此操作等等......" .这个问题不需要冗长的答案.
jQuery是一种使浏览器中的JavaScript编程更容易的方法.更短的跨浏览器命令等
AngularJS扩展了HTML,因此您不必<div>
为了创建应用程序而将所有地方放在一起.它使HTML实际上适用于应用程序,而不是它的设计目标,即静态的教育网页.它使用JavaScript以迂回的方式实现这一点,但从根本上说它是HTML的扩展,而不是JavaScript.
Sam*_*uel 61
jQuery:你对DOM元素的"查询DOM "以及做某事有很多想法.
AngularJS:模型是事实,你总是从那个角度思考.
例如,当您从要在DOM中以某种格式显示的服务器获取数据时,在jQuery中,您需要'1.找到'你要在DOM中放置这些数据的位置,'2.通过创建新节点或仅设置其innerHTML来更新/附加它.然后,当您想要更新此视图时,您将'3.找到'位置'和'4.UPDATE".在AngularJS中,在从服务器获取和格式化数据的相同上下文中完成所有查找和更新周期.
使用AngularJS,您可以获得模型(已经习惯的JavaScript对象),模型的值会告诉您模型(显然)和视图,模型上的操作会自动传播到视图,所以你不要我必须考虑一下.你会发现自己在AngularJS中不再在DOM中找到东西.
要以另一种方式,在jQuery中,你需要考虑的CSS选择器,那就是,哪里是div
或td
具有类或属性,等等,让我能得到他们的HTML或颜色或价值,但在AngularJS,你会发现自己这样想:我在处理什么模型,我会将模型的值设置为true.您不必担心反映此值的视图是复选框还是驻留在td
元素中(您在jQuery中经常需要考虑的细节).
使用AngularJS中的DOM操作,您会发现自己添加了指令和过滤器,您可以将其视为有效的HTML扩展.
你将在AngularJS中体验到的另一件事:在jQuery中你会调用jQuery函数,在AngularJS中,AngularJS会调用你的函数,所以AngularJS会"告诉你如何做事",但是它的好处是值得的,所以学习AngularJS通常意味着学习AngularJS想要的东西或者AngularJS要求你展示你的功能的方式,它会相应地调用它.这是使AngularJS成为框架而不是库的因素之一.
Dan*_*Dan 46
这些是一些非常好但很长的答案.
总结一下我的经历:
Sut*_*bey 45
jQuery是一个DOM操作库.
AngularJS是一个MV*框架.
事实上,AngularJS是为数不多的JavaScript MV*框架之一(许多JavaScript MVC工具仍属于类别库).
作为一个框架,它托管您的代码并拥有决定调用什么以及何时调用的所有权!
AngularJS本身包含一个jQuery-lite版本.因此,对于一些基本的DOM选择/操作,您实际上不必包含jQuery库(它可以节省许多字节以在网络上运行.)
AngularJS具有用于DOM操作和设计可重用UI组件的"指令"概念,因此您应该在需要执行与DOM操作相关的东西时使用它(指令只是在使用AngularJS时应该编写jQuery代码的地方).
AngularJS涉及一些学习曲线(超过jQuery :-).
- >对于任何来自jQuery背景的开发人员,我的第一个建议是"在开始使用像AngularJS这样的丰富框架之前,将JavaScript作为一流的语言学习!" 我很难学到上述事实.
祝好运.
Jin*_*Jin 34
他们是苹果和橘子.你不想比较它们.他们是两件不同的事.AngularJs已经内置了jQuery lite,它允许你执行基本的DOM操作,甚至不包括完整的jQuery版本.
jQuery完全是关于DOM操作的.它解决了所有跨浏览器的痛苦,否则你将不得不处理,但它不是一个允许你将你的应用程序划分为AngularJS等组件的框架.
AngularJs的一个好处是它允许您在指令中分离/隔离DOM操作.有内置指令可供您使用,例如ng-click.您可以创建自己的自定义指令,其中包含所有视图逻辑或DOM操作,因此您最终不会将DOM操作代码混合在应该处理业务逻辑的控制器或服务中.
Angular将您的应用分解为 - 控制器 - 服务 - 视图 - 等
还有一件事,就是指令.这是一个你可以附加到任何DOM元素的属性,你可以在其中使用jQuery,而不必担心你的jQuery与AngularJs组件发生冲突或者与其架构混淆.
我从参加过的聚会中听到,Angular的创始人之一表示他们非常努力地将DOM操作分开,所以不要试图将它们包括在内.
cod*_*sky 31
收听播客JavaScript Jabber:第32集,其中包括AngularJS的原始创作者:Misko Hevery和Igor Minar.他们谈论了从其他JavaScript背景来到AngularJS的感受,特别是jQuery.
在播客中提出的要点之一就是针对您提出了很多问题,并对您提出了问题:
MISKO:[...]我们在Angular中很难想到的事情之一是,我们如何提供大量的逃生舱,这样你就可以走出去,基本上找出一条出路.所以对我们来说,答案就是这个叫做"指令"的东西.使用指令,你基本上成为一个常规的小jQuery JavaScript,你可以做任何你想做的事情.
IGOR:因此,将指令视为编译器的指令,只要您遇到模板中的某个元素或此CSS,就会告诉它,并且您保留了这种代码,并且该代码负责元素以及该元素下面的所有内容在DOM树中.
整个剧集的成绩单可在上面提供的链接中找到.
所以,直接回答你的问题:AngularJS是非常自以为是的,是一个真正的MV*框架.但是,您仍然可以在指令中使用jQuery来完成所有非常酷的东西.这不是"我如何做我在jQuery中常用的东西?"的问题.就像"我如何使用jQuery中的所有东西来补充AngularJS一样"这个问题?
这真的是两种截然不同的心态.
San*_*ngh 23
AngularJS和jQuery:
除了JQLite功能之外,AngularJs和JQuery在每个级别都是完全不同的,一旦你开始学习AngularJs的核心功能,你就会看到它(我在下面解释过).
AngularJs是一个客户端框架,用于构建独立的客户端应用程序.JQuery是一个围绕DOM的客户端库.
AngularJs Cool Principle - 如果您希望在UI上进行一些更改,请从模型数据更改角度进行思考.更改您的数据和UI将重新呈现自己.你不需要每次都玩DOM,除非并且直到它几乎不需要,并且也应该通过Angular Directives来处理.
要回答这个问题,我想与AngularJS分享我在第一个企业应用程序上的经验.这些是Angular提供的最强大的功能,我们开始改变我们的jQuery思维模式,我们得到的Angular就像一个框架而不是库.
双向数据绑定是惊人的: 我有一个网格,所有功能都是UPDATE,DELTE,INSERT.我有一个使用ng-repeat绑定网格模型的数据对象.您只需编写一行简单的JavaScript代码即可进行删除和插入,就是这样.当网格模型立即更改时,网格会自动更新.更新功能是实时的,没有代码.你觉得很棒!
可重复使用的指令是超级的: 在一个地方写指令并在整个应用程序中使用它.我的天啊!!!我使用这些指令进行分页,正则表达式,验证等等.真的很酷!
路由很强: 由您的实现决定如何使用它,但它需要很少的代码行来路由请求以指定HTML和控制器(JavaScript)
控制器非常棒: 控制器会处理自己的HTML,但这种分离对于常见功能非常有用.如果要在主HTML上单击按钮调用相同的函数,只需在每个控制器中写入相同的函数名称并编写单个代码.
插件: 还有许多其他类似功能,例如在您的应用中显示叠加层.您不需要为它编写代码,只需使用可用作wc-overlay的覆盖插件,这将自动处理所有XMLHttpRequest(XHR)请求.
RESTful架构的理想选择: 作为一个完整的框架,AngularJS非常适合使用RESTful架构.调用REST CRUD API非常简单
服务:使用服务编写公共代码,在控制器中编写较少代码.服务可用于共享控制器之间的共同功能.
可扩展性:Angular使用angular指令扩展了HTML指令.在html中编写表达式并在运行时评估它们.创建自己的指令和服务,并在不需要额外努力的情况下在另一个项目中使用它们.
Tyb*_*itz 20
作为一个JavaScript MV*初学者,纯粹关注应用程序架构(而不是服务器/客户端问题),我肯定会推荐以下资源(我很惊讶还没有提到):JavaScript设计模式,作者:Addy Osmani ,作为不同的JavaScript设计模式的介绍.本回答中使用的术语来自上面的链接文档.我不打算在接受的答案中重复措辞.相反,这个答案链接到为AngularJS(和其他库)提供动力的理论背景.
像我一样,你会很快意识到AngularJS(或者Ember.js,Durandal和其他MV*框架)是一个复杂的框架,它汇集了许多不同的JavaScript设计模式.
我发现它也更容易,以测试(1)天然的JavaScript代码和(2)对于这些模式中的每一个更小的文库分别潜水成一个全球框架之前.这使我能够更好地理解框架所针对的关键问题(因为您个人面临问题).
例如:
注意:这个列表不完整,也不是"最好的图书馆"; 他们恰好是我用过的图书馆.这些库还包括更多模式,提到的模式只是它们的主要焦点或原始意图.如果您觉得此列表中缺少某些内容,请在评论中提及,我将很乐意添加它.
Huy*_*ran 12
实际上,如果您使用的是AngularJS,则不再需要jQuery.AngularJS本身具有绑定和指令,对于您可以使用jQuery执行的大多数事情来说,这是一个非常好的"替代".
我通常使用AngularJS和Cordova开发移动应用程序.我需要的jQuery唯一的东西是Selector.
通过谷歌搜索,我看到有一个独立的jQuery选择器模块.这是嘶嘶声.
我决定制作一个小代码片段,帮助我使用AngularJS快速启动一个网站,使用jQuery Selector(使用Sizzle).
我在这里分享了我的代码:https://github.com/huytd/Sizzular
归档时间: |
|
查看次数: |
814015 次 |
最近记录: |