aurelia.js_Aurelia与AngularJS 1.x —按功能比较的功能

aurelia.js

2016年7月23日更新 :一些人对以下事实发表了评论:本文将Aurelia与Angular 1.x(而不是Angular 2)进行了比较; 这是设计使然。 虽然Aurelia vs Angular 2的确是一个更均匀的比较,但本文的读者对象是目前已承诺使用Angular 1.x并正在寻找迁移到较新框架但不确定要迁移到的框架的人员和公司。 Angular 2需要证明不断变化的框架的成本/收益比。 我想提供详细的比较,以帮助那些用户和公司做出决定。


本文由Vildan Softic同行评审。 感谢所有SitePoint的同行评审员使SitePoint内容达到最佳状态!

在Web开发和JavaScript的世界中,我们已经看到了很多范例。 但是一个范例仍然存在:单页面Web应用程序。

过去六年来最受欢迎的框架之一是AngularJS 。 它于2010年发布并得到Google的支持,它承诺通过使用声明性双向数据绑定,可以快速,轻松地开发丰富的客户端应用程序。 AngularJS赢得了广泛的关注,并Swift将其自身确立为Web应用程序开发的首选方法,并被Amazon和Pluralsight等公司所采用。

今天,在2016年,AngularJS已开始展现其时代。 一个名为Aurelia的新框架已成为丰富的客户端应用程序的流行选择。 Aurelia主要由Durandal Inc.的Rob Eisenberg创建,目标与AngularJS相同的问题空间。 但是,Aurelia使用现代方法来简化开发并解决困扰AngularJS的许多问题。

在本文中,我们将详细介绍AngularJS和Aurelia,并比较和对比这两个框架。 为了进行比较,我们将从框架比较中排除Angular 2。 相反,我们将只关注AngularJS 1.x框架。 今天,从2016年开发人员的角度出发,我们将对2010年设计的AngularJS方法和Aurelia使用的现代方法进行逐个比较。

奥雷利亚vs角

破败不堪

AngularJS和Aurelia都是针对创建单页Web应用程序的客户端JavaScript框架。 AngularJS和Aurelia都支持直观的双向数据绑定,客户端路由和高级模板功能。 AngularJS和Aurelia都鼓励使用自定义元素扩展HTML。 AngularJS和Aurelia都附带包装通用功能的默认组件。 如前所述,AngularJS和Aurelia都针对同一问题域。 那么相似之处在哪里结束?

让我们快速看一下AngularJS和Aurelia之间的主要区别。

AngularJS 奥雷利亚
所有权 符合标准
组态 惯例
复杂 简单
昂贵 高效的
固定 灵活
单片 模块化的

哇-等一下。 您可能会说,嘿-好像您在甲板上堆了一点。 但我想深入研究这些主张。

专有(AngularJS)与标准兼容(Aurelia)

自AngularJS发布以来的六年中,Web标准得到了发展。 虽然AngularJS最初旨在遵循当时的标准,但它被迫为没有明确规则的场景创建许多专有解决方案。 其中包括JavaScript语言标准和HTML模板。

JavaScript语言标准

JavaScript的语言和生态系统正在不断发展。 它的标准,功能和语法在不断发展。 尽管AngularJS在2010年被设计为利用Web浏览器功能,但Aurelia却是在现代标准之上进行设计的。

AngularJS提供了一个非标准JavaScript模块格式实现,该实现旨在与AngularJS框架一起使用。 相比之下,Aurelia依靠ES2015模块标准。 此外,Aurelia利用新的语言构造(例如ES2016装饰器)来简化开发并支持新兴标准。

HTML模板

AngularJS和Aurelia都允许您作为开发人员以新方式扩展HTML。 创建AngularJS时,用于扩展HTML的标准尚未成熟。 因此,AngularJS创建了用于模板和自定义元素的专有解决方案。

今天,Web组件规范为模板元素和自定义元素定义了一组规则。 Aurelia积极遵守这些标准,支持Shadow DOM, <template>元素,HTML导入和本机自定义元素。

配置(AngularJS)与约定(Aurelia)

当我第一次开始使用Angular时,我认为它很棒。 学习如何使用特定的代码调用配置AngularJS并不需要花费很多时间。 但是,随着我对AngularJS的使用越来越熟悉并构建了更多的应用程序,Angular的所有配置都开始受到阻碍。

AngularJS要求您创建一个特定于Angular的模块。 本质上,在Web应用程序启动之前,您的应用程序将使用的所有内容都必须在框架中明确注册和配置。 因此,必须在使用它们之前将所有控制器,服务和自定义指令附加到AngularJS模块。 另外,AngularJS控制器通过代码耦合到视图:视图必须声明要使用的控制器。 所有这些导致了很多样板。 让我们来看一个使用ES2015的示例。

hello.js

// A Hello controller
export class Hello {
    constructor (userService) {
        this.userService = userService;
        this.greeting = "Hello, " + this.userService.getUser() + "!";
    }
};

user-service.js

// A User Service
export class UserService {
    getUser () {
        return "Newman";
    };
};

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

index.js

import {Hello} from 'hello';
import {UserService} from 'user-service';
// No matter how or where we declare our objects,
// we'll always have to use Angular's registration code
// to let AngularJS know about them.
angular.module('App', []);
    .controller('HelloCtrl', Hello)
    .service('UserService', UserService)
    ... and so on

hello.html

<div data-ng-controller="HelloCtrl as hello">
    <h1>{{hello.greeting}}</h1>
    ...my view
</div>

相比之下,Aurelia在使用组件之前不需要显式注册组件。 该框架知道如何查找视图和视图模型,而不必通过使用默认约定对它们进行显式配置。 (如果需要,可以通过配置来重写此约定,但是显式配置不是必需的。)最后,Aurelia视图模型不通过视图内部的代码耦合到视图。

hello.js

// A Hello controller
export class Hello {
    constructor (userService) {
        this.userService = userService;
        this.greeting = "Hello, " + this.userService.getUser() + "!";
    }
};

user-service.js

// A User Service
export class UserService {
    getUser () {
        return "Newman";
    };
};

index.js

// We don't need to explicitly register our objects with
// Aurelia - so really, we don't even need this.

hello.html

<template>
    <h1>${greeting}</h1>
    ...my view
</template>

这意味着Aurelia入门很容易:开发人员无需学习使用特定于框架的代码。 Aurelia的即用型惯例支持快速发展并减少学习曲线。 但是,在对Aurelia更加熟悉之后,可以根据需要更改其约定-如果不愿意,则可以处理更少的框架特定代码。

复杂(AngularJS)与简单(Aurelia)

以我在AngularJS的经验来看,虽然一些基本概念可能非常简单,但是高级概念在结构和语义上都很复杂。 有些事情(例如编写可扩展的组件和模块)还不错,而其他事情(复杂的指令)则几乎是不可思议的。 Aurelia的目标是简化其高级概念的执行过程,从而创建一条更平坦的学习曲线。

语义学

AngularJS使用复杂的语义。 开发人员必须了解它们才能真正利用该框架。 例如,在AngularJS中,您可以声明servicefactoryvalueconstant :AngularJS在所有这些之间进行了区分。 您还可以声明一个controller和一个directive 。 不幸的是,很少有这些共享相同的约定,尤其是AngularJS指令。

指令是AngularJS中的强大结构-允许应用程序使用自定义元素,属性和行为扩展HTML。 不幸的是,它们也是高级概念,学习曲线可能很陡。

解释AngularJS指令超出了本文的范围,但是请相信我。 让我们来看一个示例指令。

index.html

<body ng-controller="MainCtrl">
  <h1>What's your favorite Javascript framework?</h1>
  <choose-framework></choose-framework>
</body>

choiceFramework.html

<div>
  <input id="framework-input" type="text" ng-model="framework" placeholder="Choose a framework" />
  <button data-ng-click="choose()">Choose</button>
  <p ng-if="chosen">You prefer {{chosenFramework}}!</p>
</div>

choiceFramework.js

app.directive('chooseFramework', function() {
  return {
    scope: {
      framework: '',
      chosen: false,
    },
    restrict: 'E',
    replace: true,
    templateUrl: 'chooseFramework.html',
    link: function(scope, elem, attrs) {
      // Assume we're using jQueryUI autocomplete.
      $('#framework-input').autoComplete(['AngularJS', 'Aurelia', 'VanillaJS']);
    },
    controller: function ($scope) {
      $scope.choose = function () {
        // Log our preference somewhere.
        alert('Your framework choice has been stored for posterity.');
        $scope.chosenFramework = $scope.framework;
        $scope.chosen = true;
      }
    }
  };
});

相反,Aurelia简化了所有这些语义并减少了学习曲线。 它完全摆脱了声明步骤,使您可以以更简单的方式将代码作为依赖项注入。 此外,Aurelia使用定义良好的生命周期方法代替事件,因此代码约定在视图模型和自定义元素之间共享。 这使得编写和推理代码变得简单。 最后,奥秘的AngularJS指令声明被自定义元素替换,这些自定义元素的工作方式与Aurelia视图模型相同。

让我们来看看:

index.html

<body>
  <h1>What's your favorite Javascript framework?</h1>
  <choose-framework></choose-framework>
</body>

choiceFramework.html

<div>
  <input id="framework-input" type="text" value.bind="framework" placeholder="Choose a framework" />
  <button click.delegate="choose()">Choose</button>
  <p if.bind="chosen">You prefer ${chosenFramework}!</p>
</div>

choiceFramework.js

@customElement('choose-framework')
export class ChooseFramework {
  constructor () {
    this.framework = '';
    this.chosen = false;
  }

  attached () {
    // Assume we're using jQueryUI autocomplete.
    $('#framework-input').autoComplete(['AngularJS', 'Aurelia', 'VanillaJS']);
  }

  choose () {
    // Log our preference somewhere.
    alert('Your framework choice has been stored for posterity.');
    this.chosenFramework = this.framework;
    this.chosen = false;
  }
}
互通性

由于其更改检测的工作方式,AngularJS无法检测到框架本身不进行的对象或属性的更改。 本质上,如果在AngularJS摘要周期之外发生更改,则必须通知它以便可以将其接收。 实际上,尽管AngularJS开箱即用地提供了一些用于通用功能(例如超时,间隔和承诺)的服务包装,但这意味着任何进行更改的第三方库都必须包装以通知AngularJS发生了更改。 您最终像这样编写了许多样板代码:

$scope.$apply(function () {
    // some asynchronous activity that updates scope, such as a
    // timeout or an interval
    $scope.value = 'updated';
});

(在意识到这一点之后,您就可以了,但是在您知道发生了什么之前,您可以像我在这里所做的那样容易陷入这种陷阱。但是,意识到之后,您将不得不编写很多代码。)

Aurelia不需要这些包装,这意味着减少了占地面积并简化了约定。 这也意味着集成第三方组件和库要容易得多。

昂贵(AngularJS)与有效(Aurelia)

如果您以任何重要方式使用了AngularJS,则可能会遇到性能问题,尤其是在使用ng-repeat且列表很大的情况下。 AngularJS的性能受到其更改检测方法(脏检查)的影响。

Angular的变化检测依赖于“消化周期”。 本质上,AngularJS会定义一个时间间隔,并在每个间隔结束时“消化”自上次摘要以来发生的所有更改。 每秒发生多次。 尽管此方法有效,但它具有三个主要缺点。 首先,即使没有更改,也将每次检查每个属性。 其次,它需要持续的CPU活动。 最后,当许多属性需要更改检测时,基于时间的摘要周期将开始陷入困境。

此外,当AngularJS响应更改事件时,它将立即为该更改更新DOM。 一个摘要周期中的许多不同更改将导致大量浏览器重绘,从而造成瓶颈并损害性能。

相比之下,Aurelia的更改检测将观察实际更改的属性,而不是按设置的时间间隔扫描更改。 通过选择这种现代方法,Aurelia基本上避开了上述三个问题。 Aurelia可以使用脏检查,但这样做只能作为极端的备用。 在所有其他情况下,Aurelia的更改检测不会导致困扰AngularJS的性能问题。

最后,Aurelia不会使用每次更改来更新DOM,而是使用微任务批处理所有DOM更新,从而大大减少了完全更新视图所需的浏览器重绘次数。 这可以提高Web浏览器和移动设备的性能。

实际上,所有这些使Aurelia比AngularJS更快,更高效。 在Web浏览器环境中,这一点很重要-但在性能至关重要的移动设备上,这一点尤为重要。 但是,这也意味着作为开发人员,您可以在不影响性能的情况下对应用程序执行更多操作。

固定(AngularJS)与灵活(Aurelia)

以我在AngularJS的经验来看,它的固定约定很好用,直到遇到框架未预料到的情况。 我们将研究AngularJS和Aurelia实现之间的两个主要区别。

window.angular对象

使用AngularJS,框架假定存在一个可用的window对象:加载脚本时,它将创建一个window.angular全局变量。 Aurelia的方法放弃了过时的全局变量约定。 相反,核心框架库将导出可在任何实例中使用的Aurelia对象。

将变量附加到window并不一定是不合理的假设。 AngularJS和Aurelia都是Web框架,因此您可能会在Web浏览器中运行它们,对吗?

以我的经验,不一定是这种情况。 AngularJS中的单元测试和端到端测试需要像Karma这样的测试框架以及AngularJS的特定模拟库。 这会使测试繁重且难以设置。 ( 我自己遇到了这个问题。 )相比之下,由于Aurelia是模块化的并且不需要windowdocument ,因此测试变得更加简单。

另外,同构JavaScript在Aurelia中成为可能,而默认的AngularJS实现将永远不允许。 这也意味着我们可以创建嵌套的Aurelia应用程序-在AngularJS中进行了一些创造性的编码。

应用配置

在AngularJS中创建Web应用程序时,必须在AngularJS引导应用程序之前配置框架和所有提供程序。 由于框架的构建方式,不支持在AngularJS启动后进行配置。 因此,在您的Web应用程序启动后,您的配置是固定的,无法更改。

相比之下,Aurelia允许在运行时进行动态配置。 它确实具有在引导程序中配置应用程序的约定,但是配置不是静态的。 这使您的配置变得灵活,可以适应应用程序的需求。

一个实际的例子是Angular中的$http服务配置,而Aurelia中的HTTP服务配置。 这两个框架都允许开发人员创建“拦截器”,即可以转换传入或传出AJAX调用的中间件。 但是,AngularJS要求在应用程序启动之前定义这些拦截器-这意味着它们无法在运行时删除。 (这实际上是人们遇到现实情况 。)

整体式(AngularJS)与模块化(Aurelia)

作为开发人员,您是否曾经使用过仅适用于自己的框架? 根据我对整体框架的经验,在框架范围内进行开发将是一件轻而易举的事情。 但是一旦您需要打破常规,或者拒绝它的意见,就必须与框架抗争。

AngularJS最初是作为整体框架构建的。 它的所有组件(例如客户端路由,模板和绑定系统)都打包成一个大包。 这不仅意味着始终需要整个软件包(即使对于简单的应用程序也是如此),而且AngularJS的整体式体系结构使其难以删除组件并在必要时进行更改。 (作为示例,这在Angular的路由器组件中是显而易见的。)虽然AngularJS的更高版本通过模块化某些功能和服务在某种程度上减轻了这种情况,但核心框架本身仍然是紧密耦合的单一包。

相比之下,Aurelia采用了更现代的方法。 尽管它是一个完整的框架,但Aurelia由一组库组成,这些库使用定义明确的接口一起工作-因此它是完全模块化的。 这意味着Web应用程序仅需要包括其所需的依赖项。 而且,尽管如此,这意味着只要实现遵循定义的接口,就可以以最小的麻烦更改或交换各个组件。

作为示例,让我们以AngularJS的本机依赖项注入为例。 在我的项目中,我有多个AngularJS模块,它们以相同的名称导出服务,但是我发现本机注入器为所有模块使用单个名称空间,这意味着注册具有相同名称的服务会导致意外行为的冲突 。 我希望AngularJS模块充当单独的DI容器,以避免发生任何注入器冲突,因此我编写了一个依赖项注入组件来解决该问题。 不幸的是,由于AngularJS的服务层是AngularJS的核心组件,因此,如果不更改AngularJS的核心,我将无法摆脱它或对其进行更改。 除非重新构建框架或更改应用程序代码,否则我将陷入困境。

在Aurelia中,尽管依赖项注入是框架使用并在框架内使用的核心组件,但由于它是模块化组件,因此我可以将其替换为自己的实现,只要我遵守Aurelia的依赖项注入接口即可。 如果我发现本机注入器有问题,则可以交换自己的依赖项注入实现,而不必重新构建框架,触摸任何应用程序代码或担心依赖项组件。 根据经验,能够交换框架组件是一种非常不错的能力。

判决

现在该退后一步,回顾一下。 我们在以下方面研究了AngularJS vs Aurelia:

AngularJS 奥雷利亚
所有权 符合标准
组态 惯例
复杂 简单
昂贵 高效的
固定 灵活
单片 模块化的

……并且基于这些比较,我只能得出一个合乎逻辑的结论:

AngularJS 奥雷利亚
破烂不堪 新热点

在此比较中,听起来好像我在选择AngularJS。 老实说,我有点。 但这并不是说AngularJS是一个糟糕的框架。 我学习和使用它很有趣,并且能够用它构建一些很棒的东西。 (实际上,如果不使用太多,就无法如此详细地讨论AngularJS。)但是,AngularJS存在一些问题,这些问题在六年内还没有很好地解决。 底线是:在2016年将AngularJS和Aurelia进行一次苹果对苹果的比较时,Aurelia比AngularJS更加新鲜多汁。

问题的真相是:如果您正在考虑在像Aurelia这样的更现代的框架上选择AngularJS,则最好退后一步并重新评估。 Aurelia不难学习,拥有活跃的社区,并且对AngularJS开发人员应该有点熟悉。 但是,关于Aurelia的真正妙处在于,尽管它确实提供了合理的默认设置,但它不会迫使您的意见落在您的喉咙上-以我的经验,这意味着您可以依赖Aurelia,而不是依赖于您。 将现代框架与以开发人员为中心的方法结合使用所带来的好处无疑是值得的。

如果您有兴趣更好地了解Aurelia,请查看以下一些Aurelia资源。

入门

社区

翻译自: https://www.sitepoint.com/aurelia-vs-angular-feature-comparison/

aurelia.js

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值