“Thinking in AngularJS” if I have a jQuery background?
假设我熟悉在jquery中开发客户端应用程序,但现在我想开始使用angularjs。你能描述一下必要的范式转换吗?以下几个问题可能有助于您制定答案:
- 如何以不同的方式构建和设计客户端Web应用程序?最大的区别是什么?
- 我应该停止做/使用什么;我应该开始做/使用什么?
- 是否存在任何服务器端考虑/限制?
我不想详细比较
1。不要设计页面,然后用DOM操作更改它
在jquery中,设计一个页面,然后使其成为动态的。这是因为jquery是为增强而设计的,并且从这个简单的前提中得到了难以置信的增长。好的。
但是在安古拉基,你必须从一开始就考虑你的建筑。不是从"我有这个DOM,我想让它做X"开始,而是从你想要完成的事情开始,然后开始设计你的应用程序,最后开始设计你的视图。好的。2。不要用AngularJS扩充jQuery
同样,不要从jquery做x、y和z的想法开始,所以我将在模型和控制器上添加angularjs。当你刚开始的时候,这真的很诱人,这就是为什么我总是建议新的AngularJS开发人员不要使用jQuery,至少在他们习惯了"角度方式"之前。好的。
我在这里和邮件列表中看到过许多开发人员使用jquery插件创建了这些复杂的解决方案,这些插件包含150或200行代码,然后通过回调和
底线是:在解决问题时,首先要"用AngularJS思考";如果你想不出解决方案,请咨询社区;如果毕竟没有简单的解决方案,那么请随时联系jquery。但不要让jquery变成拐杖,否则你永远也不会掌握安古拉基。好的。三。总是从架构的角度思考
首先要知道单页应用程序是应用程序。它们不是网页。所以除了像客户端开发人员一样思考之外,我们还需要像服务器端开发人员一样思考。我们必须考虑如何将我们的应用程序划分为单独的、可扩展的、可测试的组件。好的。
那你是怎么做到的呢?你觉得安古拉基怎么样?下面是一些与jquery相比的一般原则。好的。这是"官方记录"
在jquery中,我们以编程方式更改视图。我们可以有一个下拉菜单,定义为一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <ul class="main-menu"> <li class="active"> Home </li> <li> Menu 1 <ul> <li> Submenu 1 </li> <li> Submenu 2 </li> <li> Submenu 3 </li> </ul> </li> <li> Menu 2 </li> </ul> |
在jquery中,在我们的应用程序逻辑中,我们将用如下方式激活它:好的。
1 | $('.main-menu').dropdownMenu(); |
当我们只看这个视图时,并不是很明显这里有任何功能。对于小应用来说,这很好。但是对于不平凡的应用程序,事情很快就会变得混乱和难以维护。好的。
不过,在AngularJS中,视图是基于视图功能的正式记录。我们的
1 2 3 4 | <ul class="main-menu" dropdown-menu> ... </ul> |
这两个都做同样的事情,但是在AngularJS版本中,任何查看模板的人都知道会发生什么。每当开发团队的一个新成员加入时,她都可以看到这一点,然后知道有一个名为
刚接触AngularJS的开发人员经常会问这样一个问题:我如何找到特定类型的所有链接,并向它们添加一个指令。当我们回复时,开发人员总是很震惊:你没有。但是你没有这样做的原因是,这就像半个jquery,半个angularjs,没有什么好的。这里的问题是开发人员试图在AngularJS上下文中"执行jQuery"。这永远不会奏效。这是官方记录。除了一个指令(下面将详细介绍)之外,您永远不会更改DOM。并且在视图中应用了指令,所以目的是明确的。好的。
记住:不要设计,然后标记。你必须先设计,然后再设计。好的。数据绑定
到目前为止,这是AngularJS最棒的特性之一,它消除了我在前一节中提到的对DOM进行各种操作的需求。AngularJS将自动更新您的视图,这样您就不必更新了!在jquery中,我们响应事件,然后更新内容。类似:好的。
1 2 3 4 5 6 7 8 9 10 | $.ajax({ url: '/myEndpoint.json', success: function ( data, status ) { $('ul#log').append(' <li> Data Received! </li> '); } }); |
对于类似这样的视图:好的。
1 2 3 | <ul class="messages" id="log"> </ul> |
除了混合关注点之外,我们还有同样的问题来表示我之前提到过的意图。但更重要的是,我们必须手动引用和更新一个DOM节点。如果我们想删除一个日志条目,我们也必须针对DOM进行编码。除了DOM,我们如何测试逻辑?如果我们想更改演示文稿呢?好的。
这有点凌乱,有点脆弱。但在安格拉尔,我们可以这样做:好的。
1 2 3 | $http( '/myEndpoint.json' ).then( function ( response ) { $scope.log.push( { msg: 'Data Received!' } ); }); |
我们的观点是这样的:好的。
1 2 3 4 5 6 | <ul class="messages"> <li ng-repeat="entry in log">{{ entry.msg }} </li> </ul> |
但就这一点而言,我们的观点可能是这样的:好的。
1 | {{ entry.msg }} |
现在,我们不再使用无序列表,而是使用引导警报框。我们从来不用改变控制器代码!但更重要的是,无论日志在哪里或如何更新,视图也会发生变化。自动地。整洁!好的。
虽然我没有在这里显示,但是数据绑定是双向的。因此,这些日志消息也可以在视图中进行编辑:
在jquery中,dom类似于模型。但是在AngularJS中,我们有一个独立的模型层,可以用我们想要的任何方式进行管理,完全独立于视图。这有助于上述数据绑定,保持关注点的分离,并引入更大的可测试性。其他答案提到了这一点,所以我就到此为止。好的。关注点分离
以上所有这些都与这个过度拱起的主题联系在一起:将您的关注点分开。您的视图充当应该发生的事情的正式记录(大多数情况下);您的模型表示您的数据;您有一个服务层来执行可重用的任务;您执行DOM操作并用指令扩充您的视图;您将其与控制器结合在一起。在其他答案中也提到了这一点,我唯一要补充的就是可测试性,这一点我将在下面的另一节中讨论。好的。依赖注入
帮助我们分离关注点的方法是依赖注入(DI)。如果你来自一个服务器端语言(从Java到PHP),你可能已经熟悉这个概念了,但是如果你是一个来自jQuery的客户端的家伙,这个概念可以看起来从愚蠢到多余到嬉皮士。但事实并非如此。-)好的。
从广泛的角度来看,DI意味着您可以非常自由地声明组件,然后从任何其他组件,只需请求它的一个实例,它就会被授予。您不必知道加载顺序、文件位置或类似情况。电源可能不会立即可见,但我只提供一个(常见)示例:测试。好的。
例如,在我们的应用程序中,我们需要一个通过RESTAPI实现服务器端存储的服务,还需要一个本地存储,这取决于应用程序的状态。在我们的控制器上运行测试时,我们不想与服务器通信——毕竟我们在测试控制器。我们只需添加一个与原始组件同名的模拟服务,注入器将确保我们的控制器自动获得假服务——我们的控制器不需要也不需要知道区别。好的。
说到测试…好的。4。测试驱动开发-始终
这确实是第3节架构的一部分,但它非常重要,所以我将它作为自己的顶层部分。好的。
在您所看到、使用或编写的所有jquery插件中,有多少插件具有附带的测试套件?不太多,因为jquery不太适合。但安古拉吉斯是。好的。
在jquery中,测试的唯一方法通常是使用示例/演示页独立地创建组件,我们的测试可以根据该页执行DOM操作。因此,我们必须单独开发一个组件,然后将其集成到我们的应用程序中。真不方便!很多时候,在用jquery开发时,我们选择迭代开发,而不是测试驱动开发。谁能责怪我们呢?好的。
但是因为我们有分离的关注点,所以我们可以在AngularJS中迭代地进行测试驱动开发!例如,假设我们希望一个超级简单的指令在菜单中指明我们当前的路线。我们可以在应用程序视图中声明我们想要的内容:好的。
1 | Hello |
好的,现在我们可以为不存在的
1 2 3 4 5 6 7 8 9 | it( 'should add"active" when the route changes', inject(function() { var elm = $compile( 'Hello' )( $scope ); $location.path('/not-matching'); expect( elm.hasClass('active') ).toBeFalsey(); $location.path( '/hello' ); expect( elm.hasClass('active') ).toBeTruthy(); })); |
当我们运行测试时,我们可以确认它失败了。只有现在,我们才能创建我们的指令:好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | .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' ); } }); } }; }); |
我们的测试现在通过,我们的菜单按要求执行。我们的开发是迭代和测试驱动的。邪恶的酷。好的。5。从概念上讲,指令不是打包的jquery
您经常会听到"只在指令中执行DOM操作"。这是必要的。尊重对待它!好的。
但让我们更深一点…好的。
有些指令只是修饰视图中已经存在的内容(比如
AngularJS提供了一整套工具来实现这一点;使用
我看到许多刚接触AngularJS的开发人员使用指令作为抛出一堆jQuery的地方。换句话说,他们认为"因为我不能在控制器中进行DOM操作,所以我将把代码放在一个指令中"。虽然这肯定要好得多,但它经常是错误的。好的。
想想我们在第3节中编程的记录器。即使我们把它放在一个指令中,我们仍然想用"角度的方式"来做。它仍然不需要任何DOM操作!有很多时候需要进行DOM操作,但这比您想象的要罕见得多!在应用程序中的任何地方进行DOM操作之前,先问问自己是否真的需要这样做。也许还有更好的办法。好的。
下面是一个快速的例子,展示了我最常看到的模式。我们想要一个可切换的按钮。(注意:这个例子有点做作,还有一个skosh verbose来表示以完全相同的方式解决的更复杂的情况。)好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 | .directive( 'myDirective', function () { return { template: 'Toggle me!', link: function ( scope, element, attrs ) { var on = false; $(element).click( function () { on = !on; $(element).toggleClass('active', on); }); } }; }); |
这有一些问题:好的。
此指令可以重写(即使对于非常复杂的情况!)更简单地说是这样:好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 | .directive( 'myDirective', function () { return { scope: true, template: 'Toggle me!', link: function ( scope, element, attrs ) { scope.on = false; scope.toggle = function () { scope.on = !scope.on; }; } }; }); |
同样,模板中的内容也在模板中,因此您(或您的用户)可以很容易地将其替换为满足任何必要样式的内容,并且不必触及逻辑。可重用性-轰隆!好的。
还有其他所有的好处,比如测试——很简单!无论模板中是什么,指令的内部API都不会被触及,因此重构很容易。您可以随意更改模板,而不必触摸指令。不管你做了什么改变,你的测试还是通过了。好的。
万岁!好的。
所以,如果指令不仅仅是jquery类函数的集合,那么它们是什么?指令实际上是HTML的扩展。如果HTML不做您需要它做的事情,您可以编写一个指令来为您做它,然后就像它是HTML的一部分一样使用它。好的。
换言之,如果AngularJS不做一些开箱即用的事情,那么考虑团队如何完成它,以便与
甚至不要使用jquery。甚至不包括在内。它会阻止你。当你遇到一个你认为你已经知道如何在jquery中解决的问题时,在你找到
命令式→声明式
在jquery中,选择器用于查找DOM元素,然后将事件处理程序绑定/注册到它们。当事件触发时,执行该(命令式)代码以更新/更改DOM。
在AngularJS中,您需要考虑视图而不是DOM元素。视图是包含AngularJS指令的(声明性)HTML。指令为我们在后台设置事件处理程序,并为我们提供动态数据绑定。选择器很少使用,因此对ID(和某些类型的类)的需求大大减少。视图与模型绑定(通过作用域)。视图是模型的投影。事件会更改模型(即数据、作用域属性),并且投影这些模型的视图会"自动"更新。
在AngularJS中,考虑模型,而不是jQuery选择的保存数据的DOM元素。将视图视为这些模型的投影,而不是注册回调操作用户所看到的内容。
关注点分离jquery使用不引人注目的javascript——行为(javascript)与结构(html)分离。
AngularJS使用控制器和指令(每个控制器和指令都有自己的控制器和/或编译和链接函数)从视图/结构(HTML)中删除行为。Angular还提供服务和过滤器来帮助分离/组织应用程序。
另请参阅https://stackoverflow.com/a/14346528/215945
应用程序设计设计AngularJS应用程序的一种方法:
原型继承
在不了解JavaScript原型继承如何工作的情况下,您可以使用jQuery做很多事情。在开发AngularJS应用程序时,如果您对JavaScript继承有很好的了解,那么就可以避免一些常见的陷阱。推荐阅读:AngularJS中作用域原型/原型继承的细微差别是什么?
angularjs与jQuery
一种产生超angularjs和jQuery的。如果你发现一些你可能来自jQuery surprising之差异。可以让你愤怒的角度。
这是正常的,你应该推通。角度是值得的。
大差(源)
给你的jQuery的工具包选择任意位的礼品制作他们的临时变化。你可以做你喜欢的漂亮的多件(套)。
而不是给你angularjs编译器。
这是什么那是你的全部angularjs表示为均值和礼物到顶级的底部literally对待它的指令代码的编译器。它的"礼物traverses看来,特定的指令(编译器指令)是angularjs告诉编译器该怎么做和如何表现。Javascript的对象全是小的指示,可以对类的属性匹配,标记,或甚至评论。
当编译一个角决定一场特别的礼物,它调用的指令,指令的传递函数,它在任何DOM元素的属性,目前的范围,(这是一元店,局部变量和其他一些有用的位)。这些属性可能包括interpreted表达可以由指令,告诉它如何得到它,当它应该redraw本身。
的指示,然后在转向拉杆可以在额外的组件,如角控制器,服务,等你出来的底部的形成是一个完全编译的Web应用,有线起来,准备去。
这意味着模板驱动的一角。你的模板驱动方式在JavaScript中,没有其他。这是一个激进的反转)的角色,和《JavaScript完全相反的是,我们有一个unobtrusive写作的最后十年或如此。这可以把一些要用的。
如果这听起来像它可能是只是一个以上的可能是farther和限制,从真理。"因为你的angularjs HTML代码的HTML,你会得到你的Web应用程序级别的粒度。一切事情都是可能的,和最轻松的一次surprisingly你让几个概念的跨越。
Let’s get down to the事实真相。
第一个镜头,是不是jQuery的角
jQuery的角度和不同的东西。给你angularjs集产生的Web应用程序的工具。jQuery是给你的礼物的工具修饰。如果你现在在线jQuery是一页,angularjs自动将使用它。如果它是不是与jQuery的船舶,angularjs建兴,这是切下来,但仍然perfectly jQuery的可用版本。
该插件是不是喜欢和你用它的对象。然而,你会发现,你可以提前把你漂亮的多,你所有的工作使用的组合的范围,模板和指示,你应该选择你的代码可能的,因为在这个工作流的可配置的离散将更多,更多,更多的角。
如果你使用的是jQuery的,你不应该在sprinkling它所有的地方。在正确的地方在适当的礼物是在angularjs操纵指令。更多的在线,这以后。
unobtrusive JavaScript与selectors声明模板。
jQuery是一unobtrusively typically应用。你的JavaScript代码是联在头(或英尺),这是唯一的地方,它是积极的。我们使用selectors到10位的选择和修改的插件页面写的那些部件。
《JavaScript是在控制。HTML完全独立存在的蛛网膜下腔出血。你是指没有JavaScript的HTML语义。onclick属性是非常好的做法。
一个东西你会注意我们的第一angularjs自定义属性是,到处都是。你将littered HTML属性,本质上是与NG,它的onclick属性对类固醇激素。(这是指示编译器指令),是一个主要途径,其中的模板是在钩状的模型。
当你第一次看到这一点时,你可能会想把AngularJS写成老式的侵入式JavaScript(就像我刚开始做的那样)。事实上,安古拉吉斯并不遵守这些规则。在AngularJS中,HTML5是一个模板。它由AngularJS编译以生成您的网页。好的。
这是第一大区别。对于jquery,您的网页是一个要操作的DOM。对于AngularJS,您的HTML是要编译的代码。AngularJS读取整个网页,并使用其内置的编译器将其逐字编译成一个新的网页。好的。
您的模板应该是声明性的;它的含义应该通过简单地阅读来清楚。我们使用有意义名称的自定义属性。我们用有意义的名称组成新的HTML元素。一个拥有最少的HTML知识和编程技能的设计师可以阅读你的AngularJS模板并理解它在做什么。他或她可以修改。这是角度的方法。好的。模板在驾驶座上。
当启动AngularJS并运行教程时,我问自己的第一个问题是"我的代码在哪里?".我没有写任何javascript,但是我有所有这些行为。答案是显而易见的。因为AngularJS编译DOM,所以AngularJS将HTML视为代码。对于许多简单的情况,只需编写一个模板并让AngularJS为您将其编译成一个应用程序就足够了。好的。
您的模板驱动您的应用程序。它被视为DSL。编写AngularJS组件时,AngularJS将负责将它们拉入,并根据模板的结构在正确的时间提供它们。这与标准MVC模式非常不同,其中模板仅用于输出。好的。
例如,它比Ruby on Rails更类似于XSLT。好的。
这是一种彻底的控制反转,需要一些人去适应。好的。
停止尝试从JavaScript中驱动应用程序。让模板驱动应用程序,让AngularJS负责将组件连接在一起。这也是角度的方法。好的。语义HTML与语义模型
使用jquery,您的HTML页面应该包含有语义意义的内容。如果(由用户或搜索引擎)关闭了javascript,您的内容仍然可以访问。好的。
因为AngularJS将HTML页面视为模板。模板不应该是语义的,因为您的内容通常存储在最终来自API的模型中。AngularJS用模型编译您的DOM以生成语义网页。好的。
您的HTML源不再是语义的,相反,您的API和编译的DOM是语义的。好的。
在AngularJS中,这意味着它存在于模型中,HTML只是一个模板,仅用于显示。好的。
在这一点上,您可能有各种关于SEO和可访问性的问题,并且是正确的。这里有未解决的问题。大多数屏幕阅读器现在都将解析javascript。搜索引擎也可以索引未加引号的内容。不过,您需要确保使用的是pushstate URL,并且有一个合适的站点地图。有关此问题的讨论,请参见:https://stackoverflow.com/a/23245379/687677好的。关注点分离(SOC)与MVC
关注点分离(SeparationofConcerns,SOC)是一种在多年的Web开发过程中成长起来的模式,其原因多种多样,包括SEO、可访问性和浏览器不兼容。看起来是这样的:好的。
再说一次,安古拉吉斯不按规则行事。在一次中风中,AngularJS去掉了十年来获得的智慧,而是实现了一个MVC模式,其中模板不再是语义的,甚至一点都不是。好的。
看起来是这样的:好的。
MVC是对面的末端和SOC的不同规模,他们是完全不同的方向上。使在一个芯片上angularjs义上下文。你要忘记的在线和移动。
如果你喜欢我,lived通过浏览器,你会发现这个想法很有进攻性。忘了它吧,它会是值得的,我保证。
插件的指示。
扩展jQuery插件。angularjs指令扩展的能力,你的浏览器。
我们在jQuery插件添加到函数的定义jquery.prototype)。然后,我们用这些礼物的选择钩元素和插件的调用的结果。的想法是在jQuery的扩展功能的研究。
例如,如果你想在你的酒店在线页面,你可能使用了一个列表的数据包,可能在导航元素。那么你会写一些jQuery的选择列表的页面到它的画廊和restyle滑动到与超时的动画。
在angularjs,我们定义的指令。这是一个函数的指令返回的JSON对象。这个对象看起来angularjs告诉什么是DOM元素的变化,对他们做什么。指令是指在模板用带钩的属性或元素,你发明的。该想法是扩大与新的属性和功能)的HTML元素。
该方法是一angularjs延伸功能,在本地的HTML)。你应该写的是像HTML HTML与自定义属性和元素的扩展。
如果你只是想使用旋转木马,
许多小的和大的插件和配置交换机的多。
用jquery写的《大趋势是这样大的插件,然后通过传递从我们在numerous值设置和选项。
这是一个错误,在angularjs。
在下拉走的例子。当你的写作可能是tempted插件下拉到代码中的函数:点击添加到处理程序,这是在或上或下)的变化,可能unfolded元级,显示隐藏的菜单,所有的helpful的东西。
直到你想使小的变化。
说你有一个你想展开在线菜单悬停。好,现在我们有一个问题。我们已经在我们的插件是为有线Click处理程序,我们将需要添加一个配置选项,使它在这一具体案例differently的行为。
在我们小的angularjs写指令。我们的小下拉指令将是离谱的。它可能保持折叠状态,提供折叠和展开方法,(),(),()和()的切换。这些简单的方法会更新这是一元布尔scope.menu.visible控股状态。
现在,我们可以在我们的模板上的电线。
1 2 3 4 5 | Menu <ul ng-show="menu.visible"> ... </ul> |
需要更新在线问号?
1 2 3 4 5 | Menu <ul ng-show="menu.visible"> ... </ul> |
该模板的HTML应用程序,我们得到的操作系统驱动级的粒度。如果我们想让个案例外,使这个简单的模板。
关闭与$范围
jquery插件是在一个闭包中创建的。在该封闭区域内保持隐私。在这个闭包中维护您的范围链是由您决定的。您实际上只能访问jquery传递给插件的一组dom节点,以及在闭包中定义的任何局部变量和您定义的任何全局变量。这意味着插件是完全独立的。这是一件好事,但在创建整个应用程序时可能会受到限制。尝试在动态页面的各个部分之间传递数据变得很麻烦。好的。
AngularJS有$scope对象。这些是由AngularJS创建和维护的特殊对象,您可以在其中存储模型。某些指令将生成一个新的$scope,默认情况下,它使用javascript原型继承从包装$scope继承。$scope对象可以在控制器和视图中访问。好的。
这是聪明的部分。因为$scope继承的结构大致遵循DOM的结构,所以元素可以无缝地访问自己的作用域和任何包含作用域,一直到全局$scope(与全局作用域不同)。好的。
这使得传递数据和在适当的级别存储数据变得更加容易。如果展开了下拉列表,则只有下拉$scope需要知道它。如果用户更新了他们的首选项,您可能需要更新全局$scope,并且监听用户首选项的任何嵌套作用域都将自动收到警报。好的。
这听起来可能很复杂,事实上,一旦你放松下来,就像在飞。您不需要创建$scope对象,AngularJS会根据模板层次结构正确、适当地为您实例化和配置它。然后,AngularJS使用依赖注入的魔力(稍后将详细介绍这一点)将其提供给组件。好的。手动更改DOM与数据绑定
在jquery中,您可以手动更改所有的DOM。您可以通过编程构造新的DOM元素。如果您有一个JSON数组,并且希望将它放到DOM中,那么必须编写一个函数来生成并插入HTML。好的。
在AngularJS中,您也可以这样做,但是我们鼓励您使用数据绑定。更改您的模型,并且由于DOM是通过模板绑定到它的,所以您的DOM将自动更新,不需要干预。好的。
因为数据绑定是从模板完成的,使用属性或大括号语法,所以非常容易完成。与之相关的认知开销很少,所以你会发现自己一直在做。好的。
1 | <input ng-model="user.name" /> |
将输入元素绑定到
同样地:好的。
1 2 3 4 5 | <p> {{user.name}} </p>Ok. |
将在段落中输出用户名。它是一个动态绑定,因此如果更新
在jquery中,进行Ajax调用相当简单,但这仍然是您可能会三思而后行的事情。需要考虑的是额外的复杂性,需要维护相当多的脚本。好的。
在AngularJS中,Ajax是默认的Go-to解决方案,它一直在发生,几乎没有引起您的注意。您可以包括带有ng include的模板。可以使用最简单的自定义指令应用模板。您可以在服务中包装一个Ajax调用,并创建一个GitHub服务或Flickr服务,您可以非常轻松地访问它。好的。服务对象与帮助程序函数
在jquery中,如果我们想完成一个与DOM无关的小任务,比如从API中提取提要,我们可以在闭包中编写一个小函数来完成这个任务。这是一个有效的解决方案,但是如果我们希望经常访问该提要呢?如果我们想在另一个应用程序中重用该代码呢?好的。
AngularJS为我们提供服务对象。好的。
服务是包含函数和数据的简单对象。他们总是独生子女,这意味着永远不会有超过一个。假设我们想要访问堆栈溢出API,我们可以编写一个
假设我们有一辆购物车。我们可以定义一个ShoppingCartService,它维护我们的Cart并包含添加和删除项目的方法。因为服务是单例的,并且由所有其他组件共享,所以任何需要写入购物车并从中提取数据的对象都可以。车总是一样的。好的。
服务对象是独立的AngularJS组件,我们可以根据需要使用和重用它们。它们是包含函数和数据的简单JSON对象。它们总是单例的,所以如果您将服务上的数据存储在一个地方,那么您可以通过请求相同的服务将数据从其他地方获取。好的。依赖注入(DI)与安装-又名去间隔化
AngularJS为您管理您的依赖关系。如果你想要一个对象,只要参考它,AngularJS就会为你得到它。好的。
在你开始使用它之前,很难解释这是多么巨大的时间恩惠。jquery中不存在类似angularjs di的内容。好的。
DI意味着,您不需要编写应用程序并将其连接在一起,而是定义一个组件库,每个组件都由一个字符串标识。好的。
假设我有一个名为"flickrservice"的组件,它定义了从flickr中提取JSON提要的方法。现在,如果我想写一个可以访问flickr的控制器,我只需要在声明控制器时按名称引用"flickrservice"。AngularJS将负责实例化组件并使其可用于我的控制器。好的。
例如,我在这里定义了一个服务:好的。
1 2 3 4 5 | myApp.service('FlickrService', function() { return { getFeed: function() { // do something here } } }); |
现在,当我想使用该服务时,我只是用如下名称引用它:好的。
1 2 3 | myApp.controller('myController', ['FlickrService', function(FlickrService) { FlickrService.getFeed() }]); |
AngularJS将认识到需要一个FlickrsService对象来实例化控制器,并将为我们提供一个。好的。
这使得把东西连接在一起非常容易,而且几乎消除了任何剥落的倾向。我们有一个简单的组件列表,当我们需要时,AngularJS会一个接一个地把它们交给我们。好的。模块化服务架构
jquery很少提到应该如何组织代码。安古拉吉斯有自己的看法。好的。
AngularJS为您提供了可以将代码放入其中的模块。例如,如果您正在编写一个与Flickr对话的脚本,那么您可能需要创建一个Flickr模块,将所有与Flickr相关的函数包装在其中。模块可以包括其他模块(DI)。您的主应用程序通常是一个模块,它应该包括您的应用程序所依赖的所有其他模块。好的。
您可以获得简单的代码重用,如果您想基于Flickr编写另一个应用程序,只需包含Flickr模块和Voila,就可以访问新应用程序中与Flickr相关的所有功能。好的。
模块包含AngularJS组件。当我们包含一个模块时,该模块中的所有组件将作为一个简单的列表提供给我们,这个列表由它们的唯一字符串标识。然后我们可以使用AngularJS的依赖注入机制将这些组件彼此注入。好的。总结
AngularJS和JQuery不是敌人。可以很好地在AngularJS中使用jQuery。如果您很好地使用了AngularJS(模板、数据绑定、$scope、指令等),您会发现您需要的jQuery比您可能需要的要少得多。好的。
要认识到的主要事情是您的模板驱动您的应用程序。别再尝试写什么都能做的大插件了。相反,编写一些只做一件事的小指令,然后编写一个简单的模板将它们连接在一起。好的。
少考虑不引人注目的javascript,而考虑HTML扩展。好的。我的小书
我对安古拉吉斯很兴奋,我写了一本关于它的短文,欢迎你在网上阅读http://nicholasjohnson.com/angular book/。希望能有所帮助。好的。好啊。
Can you describe the paradigm shift that is necessary?
命令式与声明式
通过jquery,您可以逐步告诉DOM需要发生什么。使用AngularJS,您可以描述您想要什么结果,但不能描述如何实现。更多信息。另外,看看马克·拉科克的答案。
How do I architect and design client-side web apps differently?
AngularJS是一个完整的客户端框架,使用MVC模式(查看它们的图形表示)。它非常关注关注关注的分离。
What is the biggest difference? What should I stop doing/using; what should I start doing/using instead?
jquery是一个库
AngularJS是一个漂亮的客户端框架,具有高度的可测试性,它结合了大量很酷的东西,如MVC、依赖注入、数据绑定等等。
它着重于关注点和测试(单元测试和端到端测试)的分离,这有助于测试驱动的开发。
最好的开始方法是通过他们的精彩教程。您可以在几个小时内完成这些步骤;但是,如果您想掌握幕后的概念,它们包括大量的参考资料,以供进一步阅读。
Are there any server-side considerations/restrictions?
您可以在已经使用纯jquery的现有应用程序上使用它。但是,如果您想充分利用AngularJS特性,可以考虑使用RESTful方法对服务器端进行编码。
这样做将使您能够利用他们的资源工厂,这将创建服务器端RESTfulAPI的抽象,并使服务器端调用(get、save、delete等)变得极其简单。
为了描述"范式转换",我认为一个简短的答案就足够了。
AngularJS改变了你寻找元素的方式在jquery中,通常使用选择器查找元素,然后将它们连接起来:
在AngularJS中,使用指令直接标记元素,并将它们连接起来:
AngularJS不需要(或不希望)您使用选择器来查找元素——AngularJS的jqlite与全面的jquery的主要区别在于jqlite不支持选择器。
所以当人们说"根本不包括jquery"时,主要是因为他们不希望您使用选择器;他们希望您学会使用指令。直接,不选择!
JQuery
jquery使得像
AngularJS允许您创建自己的HTML标记/属性,这些标记/属性可以很好地处理动态Web应用程序(因为HTML是为静态页面设计的)。
编辑:说"我有jquery的背景,在安古拉吉我怎么想?"就像是说"我有一个HTML背景,我怎么看待JavaScript?"你问这个问题的事实表明你很可能不理解这两种资源的基本目的。这就是为什么我选择通过简单地指出基本区别来回答这个问题,而不是通过列表说"AngularJS使用指令,而JQuery使用CSS选择器来生成一个JQuery对象,它执行这个和那个等操作。"这个问题不需要冗长的回答。
jquery是一种使浏览器中的JavaScript编程更容易的方法。更短、跨浏览器命令等。
AngularJS扩展了HTML,因此您不必将
jquery:您经常考虑"查询dom"中的dom元素并做一些事情。
安古拉吉斯:模型是事实,你总是从这个角度思考。
例如,当您从打算在DOM中以某种格式显示的服务器获取数据时,在jquery中,您需要'1'。在DOM中查找要放置此数据的位置,2。通过创建一个新节点或只设置其innerhtml来更新/附加"it there"。然后,当您想更新此视图时,您需要'3。找到"位置"和"4"。更新。在AngularJS中,查找和更新都是在从服务器获取和格式化数据的相同上下文中完成的。
有了AngularJS,你就有了你的模型(你已经习惯了的javascript对象),模型的值告诉你关于模型(显然)和视图的信息,模型上的操作会自动传播到视图中,所以你不必去想它。你会发现自己在安古拉吉不再在国内找到东西。
换句话说,在jquery中,需要考虑css选择器,也就是说,具有类或属性的
使用AngularJS中的DOM操作,您会发现自己添加了指令和过滤器,可以将其视为有效的HTML扩展。
在AngularJS中,还有一件事你会体验到:在jQuery中,你经常调用jQuery函数,在AngularJS中,AngularJS会调用你的函数,所以AngularJS会"告诉你怎么做",但是好处是值得的,所以学习AngularJS通常意味着学习AngularJS想要什么,或者AngularJS要求你展示你的函数的方式。它会相应地调用它。这是使AngularJS成为框架而不是库的原因之一。
这是一些非常好但冗长的答案。
总结我的经验:
jquery是一个DOM操作库。
AngularJS是一个mv*框架。
事实上,AngularJS是少数几个javascript mv*框架之一(许多javascript mvc工具仍然属于类库)。
作为一个框架,它承载您的代码,并决定调用什么和何时调用!
AngularJS本身包含一个jQueryLite版本。因此,对于一些基本的DOM选择/操作,实际上不必包括jquery库(它可以节省许多字节以便在网络上运行)。
AngularJS对于DOM操作和设计可重用的UI组件有"指令"的概念,因此当您觉得需要做与DOM操作相关的事情时,应该使用它(指令只是在使用AngularJS时应该编写jQuery代码的地方)。
AngularJS包含一些学习曲线(超过jquery:-)。
->对于任何来自jquery背景的开发人员,我的第一个建议是"在跳到像angularjs这样的富框架之前,先学习javascript作为第一类语言!"我很难理解上述事实。
祝你好运。
它们是苹果和桔子。你不想比较它们。它们是两种不同的东西。AngularJS已经内置了jQueryLite,它允许您执行基本的DOM操作,甚至不包括完整的jQuery版本。
jquery是关于DOM操作的。它解决了所有跨浏览器的难题,否则你将不得不面对,但它不是一个框架,允许你将你的应用程序划分成像AngularJS这样的组件。
AngularJS的一个优点是它允许您分离/隔离指令中的DOM操作。有一些内置指令可以供您使用,如ng click。您可以创建自己的自定义指令,该指令将包含所有视图逻辑或DOM操作,这样您就不会在应该处理业务逻辑的控制器或服务中混合DOM操作代码。
Angular将应用程序分解为-控制器-服务-视图-等等。
还有一件事,那就是指令。它是一个可以附加到任何DOM元素的属性,您可以在其中疯狂使用jquery,而不必担心jquery与AngularJS组件发生冲突或破坏其体系结构。
我从参加的一次会议上得知,Angular的一位创始人说,他们非常努力地分离出DOM操作,所以不要试图将它们重新包含进来。
收听以AngularJS:Misko Hevery&igor Minar的原始创建者为特色的播客javascript jabber:epision_32。他们谈论了很多来自其他JavaScript背景的AngularJS,特别是jQuery。
播客中的一个观点让我对你的问题有了很多了解:
MISKO: [...] one of the things we thought about very hardly in Angular is, how do we provide lots of escape hatches so that you can get out and basically figure out a way out of this. So to us, the answer is this thing called"Directives". And with directives, you essentially become a regular little jQuery JavaScript, you can do whatever you want.
IGOR: So think of directive as the instruction to the compiler that tells it whenever you come across this certain element or this CSS in the template, and you keep this kind of code and that code is in charge of the element and everything below that element in the DOM tree.
在上面提供的链接中可以找到整集的副本。
所以,直接回答你的问题:AngularJS非常固执己见,是一个真正的mv*框架。但是,您仍然可以在指令内部使用jquery来完成所有您知道并喜欢的非常酷的事情。问题不在于"我该如何做我在jquery中曾经做过的事情?"就像"如何用我在jquery中所做的所有事情来补充angularjs"一样重要。
这真的是两种截然不同的心理状态。
我发现这个问题很有趣,因为我第一次认真接触到javascript编程是node.js和angularjs。我从来没有学过jquery,我想这是件好事,因为我不需要忘记任何事情。事实上,我积极地避免jquery对我的问题的解决方案,而只是寻找一种"AngularJS方法"来解决它们。所以,我想我对这个问题的回答基本上可以归结为"像一个从未学过jquery的人一样思考",并避免任何直接合并jquery的诱惑(显然AngularJS在某种程度上在幕后使用它)。
angularjs和jQuery的:
是完全不同的angularjs和jQuery的功能,除了在每一级,你将看到它jqlite一旦你开始学习的核心功能(I angularjs它下面的解释)。
这是一angularjs客户端框架提供了构建独立的客户端应用程序。jQuery是一个库,在客户端播放的礼物。
如果你想angularjs冷原理的一些变化在你的UI模型的变化(从数据的角度来看。改变你的数据和用户界面将重新获得自己的。你需要在每个时间的礼物不是即插即用,直到它是必需的,除非是,也应该是hardly通角控制指令。
回答这个问题,我想分享我的经验,在第一次与angularjs在线企业应用。这是最出色的表现是在我们开始改变我们的角度提供jQuery的心态和我们一样没有角的框架和库。
双向数据绑定是惊人的:我有所有的功能,更新网格,三角洲,插入。我有一个日期对象的网格模型,binds NG的重复使用。你只需要写的简单的JavaScript代码是单线的插入和删除,和那是它。网格自动更新的instantly网格模型的变化。是一个实时更新的功能,是它的代码。你感到惊讶!!!!!!!!!!!!!!!
可重复使用的是超级指令:在一个写指令,整个广场和使用它的应用程序。OMG的!!!!!!!!!!!!!!!这是我用正则表达式,validations寻呼指示,等,它真的很酷!
路由算法是强大的。这是你如何实现到你想使用它,但它需要非常少的条码的请求路由到指定的控制器(HTML和JavaScript)
控制器是伟大的。控制器照顾他们自己的HTML,但这种分离是常见的功能,以及良好的工程。如果你想呼叫的功能按钮,点击网上的在线HTML高手写的函数,就在每一个人的名字和写控制代码。
插件:有许多其他类似的功能在你的应用程序显示一个类似的覆盖。你需要写代码,它使用一个插件,就可以覆盖覆盖的厕所,这将自动照顾XMLHttpRequest(XHR)的所有要求。
RESTful架构优化:作为完整的框架,使伟大的工作与angularjs RESTful架构。对REST API呼叫是非常粗和更容易
公共服务:以服务和无码写在控制器代码。服务可以被用来functionalities共享通用的控制器。
可扩展性:扩展角的角有HTML指令应用指令。表达和评价他们在写HTML在线运行。创建您自己的指令和另一个项目中使用他们的服务和没有任何额外的努力。
作为一个Javascript mv*初学者,仅仅关注应用程序架构(而不是服务器/客户端的问题),我当然会推荐以下资源(我很惊讶还没有提到):由Addy Osmani设计的Javascript设计模式,作为不同Javascript设计模式的介绍。此答案中使用的术语取自上述链接文档。我不打算重复在公认的答案中所用的措辞。相反,这个答案与支持AngularJS(和其他库)的理论背景相联系。
和我一样,您很快就会意识到AngularJS(或ember.js、Durandal和其他mv*框架)是一个复杂的框架,它组装了许多不同的JavaScript设计模式。
我发现,在深入到一个全局框架之前,为这些模式中的每一个分别测试(1)本机JavaScript代码和(2)更小的库也更容易。这使我能够更好地理解框架解决哪些关键问题(因为您亲自面对这个问题)。
例如:
- javascript面向对象编程(这是一个谷歌搜索链接)。它不是一个库,但肯定是任何应用程序编程的先决条件。它教会了我原型、构造函数、单例和装饰器模式的本地实现。
- 门面模式的jquery/underline(如用于操作DOM的wysiwyg)
- 原型/构造函数/混合模式的prototype.js
- 模块模式/amd的Requirejs/curl.js
- 可观察、发布/订阅模式的knockoutjs
注意:这个列表并不完整,也不是"最好的库";它们恰好是我使用的库。这些库还包含更多的模式,所提到的模式只是它们的主要焦点或原始意图。如果您觉得这个列表中缺少某些内容,请在评论中提及,我很乐意添加。
实际上,如果您使用的是AngularJS,那么就不再需要jQuery了。AngularJS本身具有绑定和指令,这是一个非常好的"替代"jquery的大多数功能。
我通常使用AngularJS和Cordova开发移动应用程序。我只需要jquery中的选择器。
通过谷歌搜索,我看到有一个独立的jquery选择器模块。它咝咝作响。
我决定制作一个很小的代码片段,帮助我使用jquery selector(使用sizzle)的强大功能使用angularjs快速启动一个网站。
我在这里共享了我的代码:https://github.com/huytd/sizzular