Polymer元素与AngularJS指令有何区别?

528

在 Polymer 入门 页面中,我们可以看到 Polymer 实战的一个例子:

<html>
  <head>
    <!-- 1. Shim missing platform features -->
    <script src="polymer-all/platform/platform.js"></script>
    <!-- 2. Load a component -->
    <link rel="import" href="x-foo.html">
  </head>
  <body>
    <!-- 3. Declare the component by its tag. -->
    <x-foo></x-foo>
  </body>
</html>
你会注意到<x-foo></x-foo>platform.jsx-foo.html定义。这类似于AngularJS中的指令模块。
angular.module('xfoo', [])
.controller('X-Foo', ['$scope',function($scope) {
    $scope.text = 'hey hey!';
})
.directive('x-foo', function() {
    return {
        restrict: 'EA',
        replace: true,
        controller: 'X-Foo',
        templateUrl: '/views/x-foo.html',
        link: function(scope, controller) {
        }
    };
});
  • 这两者之间有什么区别?

  • Polymer解决了哪些AngularJS未解决或未能解决的问题?

  • 是否有计划在将来将Polymer与AngularJS联系起来?


这里有有用的信息2ality - AngularJS和Polymer的角色 - LCJ
10个回答

518

在回答你的问题前,让我先澄清一些事情。你并不是第一个问这个问题的人 :)。

Polymer的webcomponents.js是一个库,其中包含了各种W3C API的polyfill,这些API属于Web Components。这些API包括:
  • Custom Elements
  • HTML Imports
  • <template>
  • Shadow DOM
  • Pointer Events
  • 其他
文档中的左侧导航栏(polymer-project.org)有一个页面介绍所有这些“平台技术”。每个页面还指向单个polyfill。 <link rel="import" href="x-foo.html">是一项HTML导入。导入是在其他HTML中包含HTML的有用工具。您可以在导入中包含<script><link>、标记或其他任何内容。
没有什么“链接”将<x-foo>与x-foo.html联系起来。在您的示例中,假设<x-foo>的自定义元素定义(例如<element name="x-foo">)在x-foo.html中定义。当浏览器看到该定义时,它会被注册为一个新元素。

接下来是问题!

Angular和Polymer有什么区别?

我们在问答视频中已经涵盖了一些内容。一般来说,Polymer是一个旨在使用(并展示如何使用)Web组件的库。它的基础是自定义元素(例如,你构建的所有东西都是Web组件),并随着Web的发展而发展。为此,我们只支持现代浏览器的最新版本。

我将使用这个图像来描述Polymer的整个架构堆栈:

enter image description here

红色层:我们通过一组polyfills获得明天的Web。请记住,随着浏览器采用新的API,这些库会随着时间而消失。

黄色层:使用polymer.js添加了一些语法糖。这一层是我们如何使用规范API的观点。它还添加了像数据绑定、语法糖、修改监视器、已发布的属性等内容...我们认为这些对于构建基于Web组件的应用程序很有帮助。

绿色层:全面的UI组件集(绿色层)仍在进行中。这些将是使用所有红色和黄色层的Web组件。

Angular指令与自定义元素?

请参阅Alex Russell的answer。基本上,Shadow DOM允许组合HTML的片段,但也是封装HTML的工具。这从根本上是Web上的一个新概念,其他框架将利用它。

Polymer解决的问题是AngularJS没有或不会出现的吗?

相似之处:声明式模板,数据绑定。

区别:Angular有针对服务、过滤器、动画等的高级API,支持IE8,并且在这一点上,是一个更强大的框架来构建生产应用。Polymer仅在alpha版中开始。
是否有计划将Polymer与AngularJS联系起来?
它们是分开的项目。话虽如此,Angular和Ember团队都宣布他们最终将使用自己框架中的基础平台API。
^ 在我看来,这是一个巨大的胜利。在web开发人员拥有强大工具(Shadow DOM、Custom Elements)的世界里,框架作者也可以利用这些原语来创建更好的框架。他们中的大多数目前都会经历很大的困难才能完成工作。
更新:
关于这个话题,有一篇非常好的文章:“这是Polymer和Angular之间的区别”。

46
这里的重点是,Polymer旨在将我们所知道的Web推向更前进的方向,特别是通过展示Web组件如何使Web开放、共享和可扩展。而AngularJS(以及Ember)则致力于创建一个框架,利用浏览器的最佳部分来创建响应式应用程序。一旦Web组件得到浏览器更好的支持,Angular和其他框架就可以基于它们进行构建,从而使框架代码更小,应用程序更简单。这就是为什么对所有人都是双赢的原因。 - Schmuli
31
我仍然不理解Polymer自定义元素和Angular指令之间的实际区别是什么?在Angular项目中,为什么我要使用Polymer自定义元素而不是Angular指令? - ronag
3
现有的Angular和Ember项目最终将从使用底层平台API中获益。但当浏览器更好地支持Web组件时,对于项目仍然使用Angular是否会有任何好处,或者它是否变得多余? - pancake
8
我认为简单明了地说,你应该在生产环境中坚持使用AngularJS,并在空闲时间玩弄Polymer,以便在需要时熟悉它。 - thdoan
31
这是一份关于 Polymer.js 的良好概述,但并没有彻底回答问题... - Christoph
显示剩余5条评论

57

2
@NREZ 好的,我不回答帖子标题,而是帖子内部的一个问题我的回答只针对第三个问题:“未来是否有将Polymer与AngularJS绑定的计划?” 我想引用AngularJS团队的原始帖子是一个好主意,你不觉得吗? - loïc m.
是的,你说得没错。只是描述可以更好一些。就像我这次做的那样,我相信下次你也会做得很好。 - NREZ
好的,谢谢你的更新 :) (我刚开始真正使用stackoverflow,所以在回复你之前我没有看到你的更新...) - loïc m.
所以他们改变了主意吗?我似乎找不到他们在哪里使用聚合物。 - theblang
我认为这不是一个答案。 - astroanu

19

19

1 & 2) Polymer组件是有作用域的,因为它们在影子DOM中具有隐藏树。这意味着它们的样式和行为不能泄漏出去。Angular不仅仅局限于你创建的特定指令,就像Polymer Web组件一样。Angular指令可能会与全局范围中的某些内容产生冲突。我认为你从Polymer中获得的好处就是我所解释的...模块化组件,具有针对该特定组件的作用域CSS和JavaScript,没有任何东西可以接触到。不可接触的DOM!

Angular指令可以被创建,以便您可以使用多个功能注释元素。在Polymer Web组件中,情况并非如此。如果您想要组合组件的功能,则将两个组件包含在另一个组件中(或将它们包装在另一个组件中),或者您可以扩展现有组件。请记住,主要区别仍然是每个组件都在Polymer Web组件中具有作用域。您可以跨多个组件共享CSS和JS文件,或者可以将其内联。

3) 是的,根据Rob Dodson和Eric Bidelman的说法,Angular计划在版本2+中合并Polymer。

有趣的是,这里没有人提到作用域这个词。我认为这是主要区别之一。

有很多不同之处,但在创建类似于乐高的应用程序模块化功能方面,它们也有很多共同点。我认为可以肯定地说,Angular将是应用程序框架,而Polymer可以与指令一起存在于同一应用程序中,主要区别在于作用域,但Polymer可能会替代您当前的许多指令。但我认为Angular完全可以按原样工作,并且还可以包括Polymer组件。
在编写此文时再次阅读答案时,我注意到Eric Bidelman(ebidel)在他的answer中确实涵盖了这一点:
“Shadow DOM允许组合HTML代码块,同时也是封装HTML代码块的工具。”
值得赞扬的是,我从听Rob Dodson和Eric Bidelman的许多采访中获得了答案。但我觉得答案没有用言辞给出这位先生想要的理解。话虽如此,我认为我已经接触到了他寻找的答案,但我绝不比Rob Dodson和Eric Bidelman拥有更多有关该主题的信息。
以下是我收集信息的主要来源。

JavaScript Jabber - 与 Rob Dodson 和 Eric Bidelman 谈论 Polymer

Shop Talk Show - 与 Rob Dodson 谈论 Web Components


1
所以,如果我使用normalize.css,它不会在 Shadow DOM 中进行规范化处理吗?那么我需要单独针对每个组件进行规范化处理,没有一种方法可以一次性完成吗?这是好事吗? - Dmitri Zaitsev
1
不要把 Shadow DOM 看作是 IFRAME。我使用这个比喻只是大致类比,因为它并不是 IFRAME。但在 IFRAME 中,你会有自己的文档,不受父文档的 CSS 和 JavaScript 页面的影响。这是非常好的事情。这意味着你可以保证特定组件按预期运行,而不会被父页面干扰。然而,如果 Shadow DOM 想要使用来自父页面的 DOM,它也可以。但那是另一个话题。 - Eric Bishard
1
我明白,是的,CSS 是一种有漏洞的语言,但在大多数情况下,可以通过在要隔离的 DOM 内使用唯一的类前缀来解决简单(虽然不完美)的问题。当然,避免使用标签和 ID 选择器也是不好的做法。另一方面,您可能实际上希望泄漏其中一些声明(例如 normalize.css 或其他基于标签的样式表),这也可以很容易地实现而无需使用 Shadow DOM。可以同意这不是完美的隔离,但在我能想到的至少 95% 的用例中都可以工作。 - Dmitri Zaitsev
2
话虽如此,我必须说我认为适当的隔离是有价值的,并且认为你的回答提供了很好的解释。 - Dmitri Zaitsev

6

Polymer是一个Web组件的shim

  • "Web Components"是HTML 5包含的一组新标准,旨在为Web应用程序提供可重复使用的构建块。

  • 各种浏览器正在实现“Web Components”规范,并且因此使用Web Components编写HTML还为时过早。

  • 但是,幸好有Polymer帮助!Polymer是一个库,它为您的HTML代码提供抽象层,使其可以像完全在所有浏览器中实现一样使用Web Components API。这称为poly-filling,Polymer团队将此库作为webcomponents.js分发。顺便说一下,以前称为platform.js

但 Polymer 不仅仅是 Web 组件的 polyfill 库...

Polymer 还通过元素提供了开放且可重用的 Web 组件构建块

enter image description here

所有元素都可以自定义和扩展。它们被用作从社交小部件到动画到Web API客户端的构建块。
Polymer不是一个Web应用程序框架。
Polymer更像是一个库而不是框架。
Polymer没有支持路由、应用程序范围、控制器等功能。
但它确实具有双向绑定,并且使用组件就像使用Angular指令一样。
尽管Polymer和AngularJS之间存在一些重叠,但它们并不相同。事实上,AngularJS团队已经提到在即将发布的版本中利用Polymer库。
还要注意,Polymer仍然被认为是“前沿技术”,而AngularJS正在稳定。
观察这两个Google项目的发展将是很有趣的!

Polymer不是一个shim或polyfill。这就是webcomponents.js polyfills的作用。Polymer是一个用于编写Web组件的库。Polymer团队还创建了一些Web组件集合(使用Polymer实现),但那些也不是“Polymer”。 - ebidel
更新:Polymer现在具有路由功能,并且非常稳定! :D - JordyvD

5
我认为从实际角度来看,最终Angular指令的模板特性和Polymer利用Web组件方法都能够完成相同的任务。据我所见,主要区别在于Polymer利用Web API包含HTML片段的方式更加语法正确且简洁,这是Angular以编程方式渲染模板所无法实现的。然而,正如所述,Polymer是一个用于构建声明性和交互式模板的小型框架,只适用于UI设计目的,并且仅支持最先进的浏览器。AngularJS 是一个完整的MVC框架,旨在通过数据绑定、依赖和指令使Web应用程序具有声明性。它们是两种完全不同的框架。至于你的问题,我认为目前使用Polymer比Angular没有任何重大好处,除了拥有数十个预构建的组件,但这仍需要将它们转换为Angular指令。然而,在未来,随着Web API变得更加先进,Web组件将彻底消除以编程方式定义和构建模板的需要,因为浏览器将能够以类似于处理JavaScript或CSS文件的方式简单地包含它们。

1
它们是两个完全不同的东西。是的,但这与问题无关。问题是关于Polymer ELEMENTS和AngularJS DIRECTIVES的区别。在许多方面,它们非常相似。我们不是在问使用哪个最好的框架.. Polymer vs AngularJS。"在我看来,目前你使用Polymer而不是Angular不会获得任何重大好处" 没有人建议这样做,事实上,我们都谈论过最终以某种方式并排使用它们。"回答你的问题,...你使用Polymer而不是Angular不会获得任何好处" 再次强调,这不是问题所在。 - Eric Bishard

0

MVVM(模型-视图,视图模型)是Angular提供的一种解决方案,而Polymer旨在解决的问题并非如此。当您考虑比较Angular和Polymer时,使用自定义标签+相关逻辑组合所提供的可组合和可重用性更为明智。Angular是一个更广泛的框架,将继续服务于多个目的。


0

Angularjs 指令是创建自定义元素的方法。您可以定义具有自定义属性的新自定义标记。Polymer 也可以实现此功能,但它会以一种有趣且更简单的方式实现。Polymer 实际上不是一个框架,而只是一个库,但它是一个强大而令人惊叹的库,你可能会爱上它(就像我一样)。 Polymer 让你学习由 W3C 制定的原生 Web 组件技术,这将被 Web 浏览器最终实现。Web 组件是未来的技术,但 Polymer 让您立即使用该技术。Google Polymer 是一个库,为使用 Web 组件构建元素和应用程序提供语法糖和 polyfills。请记住,我说过 Polymer 不是一个框架,而是一个库。但是当您使用 Polymer 时,实际上您的框架是 DOM。这篇文章讨论了 Angular js 版本 1 和 Polymer,我在我的项目中使用了两者,并个人更喜欢 Polymer 而非 Angularjs。但与 Angularjs 版本 1 相比,Angular 版本 2 完全不同,Angular 2 中的指令具有不同的含义。


0
这两者之间有什么区别?
对用户来说:差别不大,你可以使用这两种方式构建出很棒的应用程序。
对开发人员来说:它们使用截然不同的语法,因此任何一种解决方案都有相当陡峭的学习曲线。Angular已经存在了很长时间,并且拥有一个庞大的社区,因此很难找到没有被解决的问题。
对架构师来说:非常不同。Angular是一个负责您生活的应用框架。 它甚至具有垂直集成的指令,以便您可以获得组件类似的功能。另一方面,Polymer更像是按需付费。 您想要一个模态窗口,没问题,您想要一个交互式小部件,也没问题,您想要路由处理,我们也可以做到。 Polymer还更具可移植性,因为Angular需要Angualr应用程序来重用指令。 Polymer的理念是更具模块化,将适用于其他应用程序,甚至是Angular应用程序。
Polymer解决了哪些AngularJS没有或将不会解决的问题?

Polymer是一种朝着利用新的Web组件标准的方法。如果本地支持自定义元素、Shadow DOM和HTML导入等功能,不利用它们就是愚蠢的。目前大多数Web组件功能并没有得到广泛支持(当前状态),因此Polymer充当了一个桥接器或者说是一个填充器(实际上它确实使用了填充器)。

未来是否有将Polymer与AngularJS结合的计划?

我们已经在过去一年中同时使用Angular和Polymer。这个决定的一部分基于Polymer团队直接向我们承诺要提供互操作性。我们已经放弃了这个想法。我们现在正在转向只使用Polymer。

如果重新开始,我们可能不会完全采用Polymer,而是等待它成熟。尽管如此,Polymer有其优点(其中一些相当好)和缺点(其中一些非常令人沮丧),但我认为这是另一个主题的讨论。


0

Angular指令在概念上与自定义元素类似,但它们是在不使用Web组件API的情况下实现的。 Angular指令是构建自定义元素的一种方式,但Polymer和Web组件规范是基于标准的构建方法。

polymer-element:

<polymer-element name="user-preferences" attributes="email">
  <template>
    <img src="https://secure.user-preferences.com/path/{{userID}}" />
  </template>
  <script>
    Polymer('user-preferences', {
      ready: function() {
        this.userID= md5(this.email);
      }
    });
  </script>
</polymer>

Angular指令:

app.directive('user-preferences', ['md5', function() {
  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
      scope.userID= md5(attrs.email);
    },
    template: '<img src="https://secure.user-preferences.com/path/{{userID}}" />'
  };
}]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接