如果我有jQuery背景,那么“ AngularJS中的思考”吗?[关闭]

2020/10/25 23:22 · jquery ·  · 0评论

假设我熟悉使用jQuery开发客户端应用程序,但是现在我想开始使用AngularJS您能否描述必要的范式转换?以下是一些可以帮助您确定答案的问题:

  • 我如何以不同的方式设计和设计客户端Web应用程序?最大的区别是什么?
  • 我应该停止做什么/使用;我应该开始做什么/使用呢?
  • 有服务器端注意事项/限制吗?

我不希望在jQuery之间进行详细的比较AngularJS

1.不要设计您的页面,然后通过DOM操作对其进行更改

在jQuery中,您可以设计一个页面,然后将其动态化。这是因为jQuery是为增强而设计的,并且在此简单前提下得到了难以置信的增长。

但是在AngularJS中,您必须从头开始,牢记架构。您不必从“我拥有DOM的这个部分,而我想让它成为X”开始,而是必须从要完成的事情开始,然后开始设计应用程序,然后最后开始设计视图。

2.不要用AngularJS扩充jQuery

同样,不要以jQuery做X,Y和Z的想法开始,因此我只在模型和控制器的基础上添加AngularJS。这是真的,当你刚刚起步的,这就是为什么我总是建议新AngularJS开发完全不使用jQuery,至少直到他们习惯做的事情“角路”诱人。

我在这里和邮件列表上已经看到许多开发人员使用150或200行代码的jQuery插件创建这些精心设计的解决方案,然后将其粘贴到AngularJS中,并使用一系列$apply令人困惑和费解的回调和但是他们最终使它起作用了!问题在于,在大多数情况下,可以用少量代码在AngularJS中重写jQuery插件,突然之间所有事情都变得容易理解和直接了。

底线是:解决时,首先“在AngularJS中思考”;如果您想不出解决方案,请询问社区;如果毕竟,有没有简单的解决方案,然后随意达到了jQuery。但是不要让jQuery成为拐杖,否则您将永远无法掌握AngularJS。

3.总是考虑架构

首先知道单页应用程序application它们不是网页。因此,除了像客户端开发人员那样思考之外我们还需要像服务器端开发人员那样思考。我们必须考虑如何将应用程序划分为各个可扩展的可测试组件。

那么接下来怎么做呢?您如何“在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>

在jQuery中,在我们的应用程序逻辑中,我们将使用以下方式激活它:

$('.main-menu').dropdownMenu();

当我们仅查看视图时,并没有立即发现这里有任何功能。对于小型应用程序,这很好。但是对于非平凡的应用程序,事情很快就会变得混乱并且难以维护。

但是,在AngularJS中,视图是基于视图的功能的正式记录。我们的ul声明看起来像这样:

<ul class="main-menu" dropdown-menu>
    ...
</ul>

两者的作用相同,但是在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>');
  }
});

对于如下所示的视图:

<ul class="messages" id="log">
</ul>

除了混合考虑之外,我们还有我之前提到的表示意图的问题。但更重要的是,我们必须手动引用和更新DOM节点。而且,如果我们要删除日志条目,则也必须针对DOM进行编码。除了DOM,我们如何测试逻辑?如果要更改演示文稿怎么办?

这有点凌乱和脆弱。但是在AngularJS中,我们可以这样做:

$http( '/myEndpoint.json' ).then( function ( response ) {
    $scope.log.push( { msg: 'Data Received!' } );
});

我们的视图如下所示:

<ul class="messages">
    <li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>

但就此而言,我们的观点可能是这样的:

<div class="messages">
    <div class="alert" ng-repeat="entry in log">
        {{ entry.msg }}
    </div>
</div>

现在,我们使用了Bootstrap警报框,而不是使用无序列表。而且,我们无需更改控制器代码!但更重要的是,无论在何处如何更新日志,视图也会改变。自动。整齐!

尽管这里没有显示,但数据绑定是双向的。因此,这些日志信息,也可以在视图编辑只是这样做:<input ng-model="entry.msg" />有很多的欣喜。

不同的模型层

在jQuery中,DOM有点像模型。但是在AngularJS中,我们有一个单独的模型层,我们可以用它想要的任何方式进行管理,完全独立于视图。这有助于实现上述数据绑定,保持关注点分离,并引入更大的可测试性。其他答案都提到了这一点,因此我将其保留。

关注点分离

以上所有内容都与这个总体主题相关:将您的关注点分开。您的观点充当了将要发生的事情的正式记录(大部分情况下);您的模型代表您的数据;您有一个服务层来执行可重复使用的任务;您进行DOM操作并使用指令扩展视图;然后将它们与控制器粘合在一起。其他答案中也提到了这一点,我唯一要添加的内容就是可测试性,我将在下面的另一部分中进行讨论。

依赖注入

帮助我们分离关注点的是依赖注入(DI)。如果您来自服务器端语言(从JavaPHP),您可能已经很熟悉此概念,但是如果您是来自jQuery的客户端人员,那么这个概念似乎从愚蠢到多余到时髦都不是。 。但事实并非如此。:-)

从广泛的角度来看,DI意味着您可以非常自由地声明组件,然后再从任何其他组件声明它们,只需索要它的一个实例即可。您不必了解加载顺序,文件位置或类似内容。功能可能不会立即可见,但我仅提供一个(常见)示例:测试。

假设在我们的应用程序中,我们需要一个服务,该服务通过REST API以及本地存储(取决于应用程序状态)来实现服务器端存储在我们的控制器上运行测试时,我们不想与服务器进行通信-毕竟我们正在测试控制器我们只需添加一个与原始组件同名的模拟服务,然后注入器将确保我们的控制器自动获得伪造的服务-我们的控制器不需要也不知道有什么区别。

说到测试...

4.测试驱动的开发-始终

这确实是第3部分有关体系结构的一部分,但是它非常重要,因此我将其作为自己的顶层部分。

在您已经看到,使用或编写的所有jQuery插件中,有多少具有相应的测试套件?并不是很多,因为jQuery不太适合这种情况。但是AngularJS是。

在jQuery中,测试的唯一方法通常是使用示例/演示页面独立创建组件,我们的测试可以针对该示例/演示页面执行DOM操作。因此,我们必须分别开发一个组件,然后将其集成到我们的应用程序中。多么不方便!很多时候,当使用jQuery开发时,我们选择迭代而不是测试驱动的开发。谁能责怪我们?

但是因为我们有关注点分离,所以我们可以在AngularJS中迭代进行测试驱动的开发!例如,假设我们想要一个超级简单的指令,以在菜单中指示当前路线。我们可以在应用程序视图中声明我们想要的:

<a href="/hello" when-active>Hello</a>

好的,现在我们可以为不存在的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();
}));

当我们运行测试时,我们可以确认它失败了。只有现在,我们才应该创建指令:

.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操作”。这是必须的。谨慎对待它!

但是让我们深入一点...

有些指令只是修饰视图中已经存在的内容(认为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);
            });
        }
    };
});

这有一些问题:

  1. 首先,jQuery从来没有必要。我们在这里所做的一切根本不需要jQuery!
  2. 其次,即使我们的页面上已经有了jQuery,也没有理由在这里使用它。我们可以简单地使用它angular.element,当我们的组件放入没有jQuery的项目时,它仍然可以工作。
  3. 第三,即使假设jQuery的需要这种指令工作,jqLit​​e( angular.element始终使用jQuery,如果它是装的!因此我们不必使用$-我们可以使用angular.element
  4. 第四,与第三个紧密相关,是不需要包装jqLit​​e元素$-element传递给该link函数的jqLit​​e元素已经是jQuery元素!
  5. 第五,我们在前面的部分中已经提到过,为什么我们将模板内容混入逻辑中?

可以更简单地重写此指令(即使是非常复杂的情况!),如下所示:

.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;
            };
        }
    };
});

同样,模板内容在模板中,因此您(或您的用户)可以轻松地将其替换为符合任何必要样式的样式,而无需触动逻辑可重用性-繁荣!

而且还有所有其他好处,例如测试-很简单!无论模板中有什么内容,该指令的内部API都不会被触及,因此重构很容易。您可以根据需要随意更改模板,而无需触摸指令。而且,无论您进行什么更改,您的测试仍然可以通过。

w00t!

因此,如果指令不仅仅是类似jQuery的函数的集合,它们是什么?指令实际上是HTML的扩展如果HTML不能执行您需要执行的操作,则可以编写一条指令来为您执行操作,然后像使用HTML一样使用它。

换句话说,如果AngularJS没做什么开箱,认为球队如何完成它适合对符合ngClickngClass等。

概要

甚至不使用jQuery。甚至不包含它。它会让你退缩。当您遇到问题时,您认为自己已经知道如何使用jQuery解决问题,因此在$尝试之前,请尝试考虑如何在AngularJS范围内解决该问题。如果您不知道,请询问!20的19倍中,最好的方法不需要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应用程序的一种方法:

  1. 考虑一下您的模型。为这些模型创建服务或您自己的JavaScript对象。
  2. 考虑一下您要如何展示模型-您的视图。使用必要的指令获取动态数据绑定,为每个视图创建HTML模板。
  3. 将控制器附加到每个视图(使用ng-view和routing或ng-controller)。让控制器仅查找/获取视图完成其工作所需的任何模型数据。使控制器尽可能薄。

原型继承

您可以使用jQuery做很多事情,而无需了解JavaScript原型继承的工作方式。在开发AngularJS应用程序时,如果您对JavaScript继承有很好的了解,将避免一些常见的陷阱。推荐阅读:AngularJS中范围原型/原型继承的细微差别是什么?

AngularJS与jQuery

AngularJS和jQuery采用非常不同的意识形态。如果您来自jQuery,那么您可能会发现其中的一些差异令人惊讶。有角可能会让你生气。

这是正常现象,您应该努力进行。Angular是值得的。

大差异(TLDR)

jQuery为您提供了一个工具包,用于选择DOM的任意位并对其进行临时更改。您可以一步一步地完成几乎所有您想做的事情。

AngularJS却给你一个编译器

这意味着AngularJS从头到尾读取您的整个DOM,并将其视为代码,从字面上看是对编译器的指令。在遍历DOM时,它会寻找特定的指令(编译器指令),这些指令告诉AngularJS编译器如何运行以及如何执行。指令是充满JavaScript的小对象,可以与属性,标签,类甚至注释进行匹配。

当Angular编译器确定DOM的一部分与特定指令匹配时,它将调用指令函数,并向其传递DOM元素,任何属性,当前的$ scope(这是局部变量存储)以及其他一些有用的位。这些属性可能包含可由指令解释的表达式,该表达式告诉指令如何渲染以及何时应重新绘制自身。

然后,指令又可以引入其他Angular组件,例如控制器,服务等。编译器的底部是一个完整的Web应用程序,已连接好并可以使用。

这意味着Angular是模板驱动的您的模板将驱动JavaScript,而不是相反。这是角色的根本颠倒,与过去十年左右我们一直在编写的不引人注目的JavaScript完全相反。这可能需要一些时间来适应。

如果这听起来像是过于规范和限制,那么没有什么比事实更遥远了。由于AngularJS将HTML视为代码,因此您可以在Web应用程序中获得HTML级别的粒度一切皆有可能,一旦您实现了一些概念上的飞跃,大多数事情都将变得异常容易。

让我们开始讲究细节。

首先,Angular不会取代jQuery

Angular和jQuery做不同的事情。AngularJS为您提供了一组用于生成Web应用程序的工具。jQuery主要为您提供了用于修改DOM的工具。如果页面上存在jQuery,AngularJS将自动使用它。如果不是这样,AngularJS会附带jQuery Lite,它是jQuery的精简版,但仍可完美使用。

Misko喜欢jQuery,并不反对使用它。但是,随着前进,您会发现可以使用范围,模板和指令的组合来完成几乎所有的工作,并且您应尽可能使用此工作流,因为您的代码将更加分散,更可配置且更多有角度的。

如果您确实使用jQuery,则不应将其散布到各处。在AngularJS中进行DOM操作的正确位置是在指令中。稍后再详细介绍。

带有选择器和声明性模板的不干扰JavaScript

jQuery通常会毫不客气地应用。您的JavaScript代码链接在页眉(或页脚)中,这是唯一提到的地方。我们使用选择器来挑选页面的一部分,并编写插件来修改这些部分。

JavaScript受控制。HTML具有完全独立的存在。即使没有JavaScript,HTML仍然保持语义。Onclick属性是非常不好的做法。

关于AngularJS的第一件事就是自定义属性无处不在您的HTML会有ng属性,实际上是类固醇的onClick属性。这些是伪指令(编译器伪指令),是模板与模型挂钩的主要方式之一。

当您第一次看到此内容时,您可能会想将AngularJS改写为老式的侵入式JavaScript(就像我刚开始一样)。实际上,AngularJS并不遵循这些规则。在AngularJS中,您的HTML5是模板。它由AngularJS编译以生成您的网页。

这是第一个大区别。对于jQuery,您的网页是要操作的DOM。对于AngularJS,您的HTML是要编译的代码。AngularJS读取整个网页,并使用其内置的编译器将其按字面意义编译为新网页。

您的模板应该是声明性的;只需阅读即可清楚了解其含义。我们使用具有有意义名称的自定义属性。我们用有意义的名称组成新的HTML元素。仅有很少的HTML知识并且没有编码技能的设计人员可以阅读您的AngularJS模板并了解其功能。他或她可以进行修改。这是角度的方式。

模板在驾驶座上。

启动AngularJS并运行教程时,我问自己的第一个问题是“我的代码在哪里?” 我没有编写JavaScript,但是我有所有这些行为。答案是显而易见的。由于AngularJS会编译DOM,因此AngularJS会将HTML视为代码。在许多简单的情况下,只需编写一个模板并将AngularJS编译成适合您的应用程序通常就足够了。

您的模板驱动您的应用程序。它被视为DSL您编写了AngularJS组件,AngularJS将根据模板的结构将它们拉入并在适当的时间使其可用。这与标准MVC模式非常不同,在标准MVC模式中,模板仅用于输出。

例如,它Ruby on Rails更类似于XSLT

这是控制的根本反转,需要一些时间来习惯。

停止尝试从JavaScript驱动应用程序。让模板驱动应用程序,让AngularJS负责将组件连接在一起。这也是Angular方式。

语义HTML与语义模型

使用jQuery,您的HTML页面应包含有意义的语义内容。如果关闭了JavaScript(由用户或搜索引擎关闭),您的内容仍然可以访问。

因为AngularJS将您的HTML页面视为模板。模板不应该是语义的,因为您的内容通常存储在最终来自API的模型中。AngularJS使用模型编译您的DOM,以生成一个语义网页。

HTML源不再是语义的,而是API和已编译的DOM是语义的。

在AngularJS中,含义存在于模型中,HTML只是一个模板,仅用于显示。

在这一点上,您可能会遇到有关SEO和可访问性的各种问题,这是正确的。这里有未解决的问题。现在,大多数屏幕阅读器都会解析JavaScript。搜索引擎还可以索引AJAX内容。不过,您将要确保使用的是推状态网址,并且站点地图不错。请参阅此处以获取有关该问题的讨论:https : //stackoverflow.com/a/23245379/687677

关注点分离(SOC)与MVC

关注分离(SOC)是Web开发多年来发展起来的一种模式,其原因包括SEO,可访问性和浏览器不兼容等多种原因。看起来像这样:

  1. HTML-语义。HTML应该独立存在。
  2. CSS-样式,没有CSS的页面仍然可读。
  3. JavaScript-行为,如果没有脚本,内容将保留。

同样,AngularJS并不遵守他们的规则。很快AngularJS放弃了十年的智慧,而是实现了一种MVC模式,其中模板不再是语义,甚至不再是语义。

看起来像这样:

  1. 模型-您的模型包含您的语义数据。模型通常是JSON对象。模型作为称为$ scope的对象的属性存在。您还可以将方便的实用程序功能存储在$ scope上,然后可以使用它们访问模板。
  2. 视图-您的视图以HTML编写。视图通常不是语义的,因为您的数据存在于模型中。
  3. 控制器-您的控制器是一个JavaScript函数,可将视图连接到模型。它的功能是初始化$ scope。根据您的应用程序,您可能需要创建控制器,也可能不需要。一个页面上可以有许多控制器。

MVC和SOC不在相同规模的相对两端,它们在完全不同的轴上。在AngularJS上下文中,SOC没有意义。您必须忘记它并继续前进。

如果像我一样,经历了浏览器大战,您可能会发现这个想法令人反感。克服它,这是值得的,我保证。

插件与指令

插件扩展了jQuery。AngularJS指令扩展了浏览器的功能。

在jQuery中,我们通过向jQuery.prototype添加函数来定义插件。然后,通过选择元素并在结果上调用插件,将它们挂接到DOM中。这个想法是为了扩展jQuery的功能。

例如,如果要在页面上使用轮播,则可以定义无序的图形列表,也许将其包装在nav元素中。然后,您可以编写一些jQuery以选择页面上的列表,然后将其重新设置为具有超时功能的图库,以进行滑动动画处理。

在AngularJS中,我们定义了指令。指令是一个返回JSON对象的函数。该对象告诉AngularJS寻找什么DOM元素,以及对其进行哪些更改。使用您发明的属性或元素将指令连接到模板。这个想法是用新的属性和元素扩展HTML的功能。

AngularJS的方法是扩展原生HTML的功能。您应该编写类似于HTML的HTML,并使用自定义属性和元素进行扩展。

如果您想要旋转木马,只需使用一个<carousel />元素,然后定义一个指令以拉入模板,并使该吸盘工作。

许多小型指令与带有配置开关的大型插件

jQuery的趋势是编写很棒的大型插件,例如lightbox,然后我们通过传入大量值和选项进行配置。

这是AngularJS中的错误。

以下拉列表为例。编写下拉插件时,您可能会喜欢在单击处理程序中编写代码,或者是在向上或向下添加人字形的函数,可能会更改展开元素的类,显示隐藏菜单,所有有用的东西。

直到您想做一点零钱。

假设您有一个要悬停展开的菜单。好吧,现在我们有一个问题。我们的插件已连接到我们的点击处理程序中,我们将需要添加一个配置选项以使其在这种特定情况下表现不同。

在AngularJS中,我们编写了较小的指令。我们的下拉指令太小了。它可能会保持折叠状态,并提供fold(),unfold()或toggle()的方法。这些方法将简单地更新$ scope.menu.visible这是一个持有状态的布尔值。

现在,在我们的模板中,我们可以将其连接起来:

<a ng-click="toggle()">Menu</a>
<ul ng-show="menu.visible">
  ...
</ul>

是否需要更新鼠标悬停?

<a ng-mouseenter="unfold()" ng-mouseleave="fold()">Menu</a>
<ul ng-show="menu.visible">
  ...
</ul>

模板驱动应用程序,因此我们获得了HTML级别的粒度。如果我们希望逐个案例地进行例外处理,则模板可以使此操作变得容易。

闭包与$ scope

jQuery插件是在闭包中创建的。在此关闭内维护隐私。取决于您在该闭包内维护范围链。您实际上只能访问jQuery传递给插件的DOM节点集,以及在闭包中定义的任何局部变量以及您定义的任何全局变量。这意味着插件是完全独立的。这是一件好事,但在创建整个应用程序时可能会受到限制。试图在动态页面的各个部分之间传递数据变得很麻烦。

AngularJS具有$ scope对象。这些是由AngularJS创建和维护的特殊对象,您可以在其中存储模型。某些指令将产生一个新的$ scope,默认情况下,该$ scope使用JavaScript原型继承从其包装的$ scope继承。$ scope对象可在控制器和视图中访问。

这是聪明的部分。因为$ scope继承的结构大致遵循DOM的结构,所以元素可以无缝访问它们自己的范围以及任何包含的范围,一直到全局$ scope(与全局范围不同)。

这样可以更轻松地传递数据并以适当的级别存储数据。如果展开下拉列表,则仅下拉列表$ scope需要知道它。如果用户更新了他们的首选项,则可能要更新全局$ scope,并且监听用户首选项的任何嵌套作用域都将自动得到警报。

这听起来可能很复杂,实际上,一旦您放松一下,就好像在飞翔。您无需创建$ scope对象,AngularJS会根据您的模板层次结构正确,适当地实例化并为您配置它。然后,AngularJS使用依赖注入的魔力将其提供给您的组件(稍后会对此进行更多介绍)。

手动DOM更改与数据绑定

在jQuery中,您可以手动更改所有DOM。您可以通过编程方式构造新的DOM元素。如果您有JSON数组并将其放入DOM,则必须编写一个函数来生成HTML并将其插入。

在AngularJS中,您也可以这样做,但建议您使用数据绑定。更改模型,由于DOM是通过模板绑定到模型的,因此DOM将自动更新,无需干预。

因为数据绑定是使用属性或大括号语法从模板完成的,所以它非常容易实现。与之相关的认知开销很小,因此您会发现自己一直在这样做。

<input ng-model="user.name" />

将输入元素绑定到$scope.user.name更新输入将更新您当前作用域中的值,反之亦然。

同样地:

<p>
  {{user.name}}
</p>

将在一个段落中输出用户名。这是实时绑定,因此,如果$scope.user.name值被更新,模板也将更新。

一直都是Ajax

在jQuery中,进行Ajax调用非常简单,但这仍然是您可能三思而后行的事情。需要考虑的额外复杂性以及需要维护的大量脚本。

在AngularJS中,Ajax是您的默认入门解决方案,并且它一直在发生,几乎没有引起您的注意。您可以将模板包含在ng-include中。您可以使用最简单的自定义指令来应用模板。您可以将Ajax调用包装在服务中,并创建自己的GitHub服务或Flickr服务,您可以轻松访问它们。

服务对象与助手功能

在jQuery中,如果我们想完成一个小的非dom相关的任务,例如从API中提取提要,我们可以在闭包中编写一个小函数来实现。那是一个有效的解决方案,但是如果我们要经常访问该提要怎么办?如果我们想在另一个应用程序中重用该代码怎么办?

AngularJS给了我们服务对象。

服务是包含功能和数据的简单对象。它们始终是单例,这意味着不能超过一个。假设我们要访问Stack Overflow API,我们可以编写一个StackOverflowService定义用于执行此操作的方法的。

假设我们有一个购物车。我们可能会定义一个ShoppingCartService来维护我们的购物车,并包含用于添加和删除商品的方法。因为该服务是单例服务,并且由所有其他组件共享,所以任何需要写入的对象都可以写入购物车并从中提取数据。总是一样的购物车。

服务对象是独立的AngularJS组件,我们可以根据需要使用和重用它们。它们是包含功能和数据的简单JSON对象。它们始终是单例,因此,如果将数据存储在某个位置的某个服务上,则只需请求相同的服务就可以从其他位置获取数据。

依赖注入(DI)与状态化-又名去意大利化

AngularJS为您管理依赖项。如果您想要一个对象,只需引用它,AngularJS就会为您获取它。

除非您开始使用它,否则很难解释这是多么宝贵的时间。jQuery中没有像AngularJS DI那样的东西。

DI意味着您无需定义应用程序并将其连接在一起,而是可以定义一个组件库,每个组件由一个字符串标识。

假设我有一个名为“ FlickrService”的组件,该组件定义了用于从Flickr提取JSON提要的方法。现在,如果我要编写一个可以访问Flickr的控制器,则在声明该控制器时,只需按名称引用“ FlickrService”即可。AngularJS将负责实例化该组件并将其提供给我的控制器。

例如,在这里定义服务:

myApp.service('FlickrService', function() {
  return {
    getFeed: function() { // do something here }
  }
});

现在,当我想使用该服务时,只需按如下名称命名即可:

myApp.controller('myController', ['FlickrService', function(FlickrService) {
  FlickrService.getFeed()
}]);

AngularJS将认识到需要一个FlickrService对象来实例化控制器,并将为我们提供一个对象。

这样可以很容易地将事物连接在一起,并且几乎消除了任何可能出现幼化的趋势。我们有一个简单的组件列表,AngularJS在需要时将它们逐一交给我们。

模块化服务架构

jQuery很少说明应如何组织代码。AngularJS有意见。

AngularJS为您提供了可以在其中放置代码的模块。例如,如果您正在编写与Flickr对话的脚本,则可能要创建一个Flickr模块来包装所有与Flickr相关的功能。模块可以包含其他模块(DI)。您的主应用程序通常是一个模块,并且应包括您的应用程序将依赖的所有其他模块。

您将获得简单的代码重用,如果您要基于Flickr编写另一个应用程序,则可以仅包含Flickr模块和voila,您可以在新应用程序中访问所有与Flickr相关的功能。

模块包含AngularJS组件。当我们包含一个模块时,该模块中的所有组件都可以作为由其唯一字符串标识的简单列表来使用然后,我们可以使用AngularJS的依赖项注入机制将这些组件相互注入。

总结一下

AngularJS和jQuery不是敌人。可以在AngularJS中很好地使用jQuery。如果您很好地使用了AngularJS(模板,数据绑定,$ scope,指令等),您会发现所需的jQuery比您可能需要的少得多。

要认识的主要是模板驱动您的应用程序。停止尝试编写能做所有事情的大插件。而是编写一些只做一件事的小指令,然后编写一个简单的模板将它们连接在一起。

少考虑不干扰JavaScript的内容,而应考虑HTML扩展。

我的小书

我对AngularJS感到非常兴奋,为此写了一本简短的书,非常欢迎您在线阅读http://nicholasjohnson.com/angular-book/希望对您有所帮助。

您能否描述必要的范式转换?

命令式与声明式

使用jQuery,您可以逐步告诉DOM需要做什么。使用AngularJS,您可以描述所需的结果,而不是所需的结果。更多关于此这里另外,请查看Mark Rajcok的答案。

我如何以不同的方式设计和设计客户端Web应用程序?

AngularJS是使用MVC模式的完整客户端框架(请查看其图形表示)。它极大地侧重于关注点分离。

最大的区别是什么?我应该停止做什么/使用;我应该开始做什么/使用呢?

jQuery是一个库

AngularJS是一个漂亮的客户端框架,可测试性强,它结合了许多很酷的东西,例如MVC,依赖注入,数据绑定等等。

它着重于关注点和测试的分离单元测试和端到端测试),这有助于测试驱动的开发。

最好的开始方法是阅读他们很棒的教程您可以在几个小时内完成所有步骤;但是,如果您想掌握幕后的概念,则其中包含许多参考资料供进一步阅读。

有服务器端注意事项/限制吗?

您可以在已经使用纯jQuery的现有应用程序上使用它。但是,如果您想充分利用AngularJS功能,则可以考虑使用RESTful方法对服务器端进行编码

这样做将使您能够利用它们的资源工厂,这将创建服务器端RESTful API的抽象,并使服务器端调用(获取,保存,删除等)变得异常简单。

为了描述“范式转换”,我认为简短的回答就足够了。

AngularJS改变了查找元素的方式

jQuery中,通常使用选择器查找元素,然后将它们连接起来:
$('#id .class').click(doStuff);

AngularJS中,您使用指令直接标记元素,以将它们连接起来:
<a ng-click="doStuff()">

AngularJS不需要(也不希望)使用选择器来查找元素-AngularJSjqLit​​e与成熟的jQuery之间的主要区别jqLit​​e不支持选择器

因此,当人们说“根本不包括jQuery”时,主要是因为他们不希望您使用选择器。他们希望您学习使用指令。直接,不选!

jQuery的

jQuery制作了很长的JavaScript命令,例如getElementByHerpDerp更短和跨浏览器。

AngularJS

AngularJS允许您创建自己的HTML标记/属性,以使这些标记/属性能够与动态Web应用程序一起很好地工作(因为HTML是为静态页面设计的)。

编辑:

说“我有一个jQuery背景,我在AngularJS中如何看待?” 就像说“我有HTML背景,我如何看待JavaScript?” 您提出问题的事实表明您很可能不了解这两种资源的基本目的。这就是为什么我选择通过简单地指出根本差异而不是在列表中遍历“ AngularJS使用指令,而jQuery使用CSS选择器来创建执行此操作的jQuery对象……”来回答问题。 。这个问题不需要冗长的答案。

jQuery是一种使浏览器中的JavaScript编程更容易的方法。更短的跨浏览器命令等

AngularJS扩展了HTML,因此您不必为了编写<div>应用程序而花很多精力它使HTML实际上可用于应用程序,而不是为静态的教育性网页设计的。它使用JavaScript以一种about回的方式来完成此任务,但从根本上讲,它是HTML的扩展,而不是JavaScript。

jQuery:您对DOM元素的“查询DOM ”进行了很多思考

AngularJS:模型就是事实,您总是从那个角度思考。

例如,当您从服务器获取要以某种格式显示在DOM中的数据时,在jQuery中,您需要将其设置为'1。查找”,在DOM中要放置此数据的位置“ 2”。通过创建一个新节点或仅设置其innerHTML来进行“更新/添加” 然后,当您要更新此视图时,请输入'3。查找“位置”和“ 4。更新”。AngularJS中没有在从服务器获取和格式化数据的同一上下文中完成所有查找和更新的循环。

使用AngularJS,您可以拥有模型(您已经习惯了JavaScript对象),并且模型的值可以告诉您有关模型(显然)和视图的信息,并且对模型的操作会自动传播到视图,因此您无需不必考虑。您将发现自己在AngularJS中不再在DOM中找到东西。

要以另一种方式,在jQuery中,你需要考虑CSS选择器,那就是,哪里是divtd具有类或属性,等等,让我能得到他们的HTML或颜色或价值,但在AngularJS,您会发现自己的想法是这样的:我要处理的模型是什么,我将模型的值设置为true。您不必担心反映此值的视图是复选框还是驻留在td元素中(详细信息,您通常需要在jQuery中进行思考)。

通过AngularJS中的DOM操作,您发现自己添加了指令和过滤器,可以将其视为有效的HTML扩展。

您将在AngularJS中体验到另一件事:在jQuery中,您经常调用jQuery函数;在AngularJS中,AngularJS将调用您的函数,因此AngularJS将“告诉您如何做事”,但是好处是值得的,因此学习AngularJS通常意味着学习AngularJS想要什么或AngularJS要求您呈现函数的方式,它将相应地调用它。这是使AngularJS成为框架而不是库的原因之一。

这些是很好的答案,但答案冗长。

总结一下我的经验:

  1. 控制器和提供者(服务,工厂等)用于修改数据模型,而不是HTML。
  2. HTML和指令定义布局并绑定到模型。
  3. 如果您需要在控制器之间共享数据,请创建服务或工厂-它们是在应用程序中共享的单例。
  4. 如果需要HTML小部件,请创建指令。
  5. 如果您有一些数据,现在正尝试更新HTML,请停止!更新模型,并确保您的HTML已绑定到模型。

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作为一流的语言学习!” 我很难学到上述事实。

祝好运。

他们是苹果和橘子。您不想比较它们。他们是两回事。AngularJs已经内置了jQuery lite,它允许您执行基本的DOM操作,甚至不包括完整的jQuery版本。

jQuery全部涉及DOM操作。它解决了所有跨浏览器的烦恼,否则您将不得不面对,但它不是一个框架,可让您将应用程序划分为AngularJS之类的组件。

关于AngularJs的一件好事是,它允许您在指令中分隔/隔离DOM操作。有内置指令可供您使用,例如ng-click。您可以创建自己的自定义指令,其中将包含所有视图逻辑或DOM操作,这样您就不会最终在应该处理业务逻辑的控制器或服务中混合DOM操作代码。

Angular将您的应用细分为-控制器-服务-视图-等

还有一件事,那就是指令。它是一个属性,可以附加到任何DOM元素,并且可以在其中使用jQuery,而不必担心jQuery与AngularJs组件发生冲突或使其体系结构混乱。

我从参加的聚会中听说,Angular的一位创始人表示,他们非常努力地将DOM操作分离出来,因此不要尝试将其重新加入。

收听播客JavaScript Jabber:第32集,其中介绍了AngularJS的原始创建者:Misko Hevery和Igor Minar。他们谈论了来自其他JavaScript背景(尤其是jQuery)的AngularJS的感受。

在播客中提出的观点之一,就您的问题而言,很多事情对我来说都很重要:

MISKO:[...]我们在Angular中很少想到的一件事是,我们如何提供大量的逃生舱口,以便您可以走出来并从根本上找出解决办法。所以对我们来说,答案就是这个叫做“指令”的东西。有了指令,您实际上就变成了普通的小型jQuery JavaScript,您可以做任何想做的事情。

IGOR:因此,可以将指令视为编译器的指令,当您在模板中遇到此特定元素或此CSS时便会告诉它,并保留此类代码,并且该代码负责该元素以及该元素下的所有内容在DOM树中。

整个情节的笔录可从上面提供的链接获得。

因此,直接回答您的问题:AngularJS是非常有思想的,并且是一个真正的MV *框架。但是,您仍然可以在指令内部使用jQuery完成所有您知道和喜欢的很棒的工作。这与“我该如何执行jQuery中以前的工作?”无关紧要。只是“我如何用以前在jQuery中所做的所有事情补充AngularJS?”

这实际上是两种截然不同的心态。

我发现这个问题很有趣,因为我最先接触JavaScript编程的是Node.js和AngularJS。我从来没有学过jQuery,我想那是一件好事,因为我不必学习任何东西。实际上,我积极地避免了针对我的问题的jQuery解决方案,而是仅寻找“ AngularJS方式”来解决它们。因此,我想我对这个问题的回答基本上可以归结为“像从未学习过jQuery的人一样思考”,并避免了直接集成jQuery的任何诱惑(显然AngularJS在后台使用了它)。

AngularJS和jQuery:

除了JQLite功能之外,每个级别的AngularJs和JQuery都完全不同,一旦您开始学习AngularJs的核心功能(我在下面解释了),您就会看到它。

AngularJs是一个客户端框架,可用来构建独立的客户端应用程序。JQuery是一个围绕DOM播放的客户端库。

AngularJs酷原则-如果要在UI上进行一些更改,请从模型数据更改角度考虑。更改数据,UI会重新呈现。除非并直到几乎没有要求,否则您不必每次都在DOM上玩耍,并且也应该通过Angular Directives处理。

为了回答这个问题,我想与AngularJS分享我在第一个企业应用程序上的经验。这些是Angular提供的最出色的功能,我们可以从这些功能开始改变jQuery的思维方式,并像框架一样获得Angular,而不是获得库。

双向数据绑定是惊人的:
我拥有一个具有所有功能UPDATE,DELTE,INSERT的网格。
我有一个使用ng-repeat绑定网格模型的数据对象。您只需要编写一行简单的JavaScript代码即可进行删除和插入,仅此而已。网格模型立即更改时,网格会自动更新。更新功能是实时的,没有代码。你感觉棒极了!!!

可重用指令是超级的:
在一个地方编写指令,并在整个应用程序中使用它。
我的天啊!!!我将这些指令用于分页,正则​​表达式,验证等。这真的很棒!

路由功能很强大:
取决于您的实现方式,但要用很少的代码行来路由请求以指定HTML和控制器(JavaScript)

控制器很棒:
控制器照顾自己的HTML,但是这种分离对于通用功能也很有效。
如果要单击主HTML上的按钮来调用相同的函数,只需在每个控制器中编写相同的函数名称并编写单独的代码即可。

插件:
还有许多其他类似功能,例如在您的应用程序中显示覆盖图。
您不需要为此编写代码,只需使用可作为wc-overlay使用的overlay插件,它将自动处理所有
XMLHttpRequest(XHR)请求。

RESTful体系结构的理想选择
完整的框架使AngularJS非常适合与RESTful体系结构一起使用。
调用REST CRUD API非常容易,而且

服务:使用服务编写通用代码,而在控制器中编写更少的代码。服务可以用来在控制器之间共享通用功能。

可扩展性:Angular已使用angular指令扩展了HTML指令。在html内编写表达式,并在运行时对其求值。创建您自己的指令和服务,并在其他项目中使用它们,而无需付出额外的努力。

作为JavaScript MV *的初学者,并且只专注于应用程序体系结构(而不​​是服务器/客户端问题),我当然会推荐以下资源(我还没有提到它很惊讶):JavaScript设计模式,作者:Addy Osmani ,介绍不同的JavaScript设计模式该答案中使用的术语取自上面的链接文档。我不会在已接受的答案中重复非常好的措词。相反,此答案可以链接到为AngularJS(和其他库)提供支持的理论背景

像我一样,您会很快意识到AngularJS(或Ember.js,Durandal以及其他MV *框架)是一个复杂的框架,它集合了许多不同的JavaScript设计模式。

我发现它也更容易,以测试(1)天然的JavaScript代码和(2)对于这些模式中的每一个更小的文库分别潜水成一个全球框架之前。这使我可以更好地了解框架解决了哪些关键问题(因为您亲自面对该问题)。

例如:

  • JavaScript面向对象编程(这是Google搜索链接)。它不是一个库,但肯定是任何应用程序编程的先决条件。它教会了我原型,构造函数,单例和装饰器模式的本地实现
  • jQuery /下划线用于外观模式(例如用于操纵DOM的WYSIWYG)
  • Prototype.js用于原型/构造器/混合模式
  • RequireJS / Curl.js用于模块模式/ AMD
  • 淘汰赛用于可观察的发布/订阅模式

注意:此列表不完整,也不是“最佳图书馆”;它们恰好是我使用的库。这些库还包含更多模式,其中提到的只是它们的主要重点或原始意图。如果您觉得此列表中缺少某些内容,请在评论中提及它,我们将很高兴添加它。

实际上,如果您使用的是AngularJS,则不再需要jQuery。AngularJS本身具有绑定和指令,对于您可以使用jQuery进行的大多数操作来说,这是一个很好的“替代品”。

我通常使用AngularJS和Cordova开发移动应用程序我唯一需要的jQuery是Selector。

通过谷歌搜索,我看到那里有一个独立的jQuery选择器模块。是嘶嘶声。

然后,我决定制作一个很小的代码段,以帮助我借助jQuery Selector(使用Sizzle)使用AngularJS快速启动网站。

我在这里分享了我的代码:https : //github.com/huytd/Sizzular

本文地址:http://jquery.askforanswer.com/ruguowoyoujquerybeijingname-angularjszhongdesikaomaguanbi.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!