将Polymer或Web Components模板链接/编译为Angularjs Scope

时间:2013-09-27 10:43:15

标签: angularjs polymer

我有一个Polymer组件(web组件),我在其中放置了一个角度控制器,如下所示:

<polymer-element name="x-display"
  attributes="title body">
  <template>
    <h2>{{title}}</h2>
    <p>{{body}}</p>
    <p ng-controller="XDisplayController" ng-bind="text"></p>
  </template>
  <script>
    Polymer('x-display', {
      title: "",
      body: ""
    });
  </script>
</polymer-element>

<x-display>被放置在页面上,如下所示:

<div ng-controller="PeopleController">
    <h1>People</h1>
    <input ng-model="query" type="text">
    <x-display ng-repeat="p in people | filter:query" 
        title="{{ p.name }}" body="{{ p.body }}"></x-display>
</div>

这一切都很酷。除了一个例外,它的行为与您期望的完全相同,放置一大堆<x-display>标签,每个人一个,并用正确的值填充它们。我调用Polymer默认值为null,以便{{ p.value }}次出现不会闪现但除此之外它很简单。

问题是嵌套的XDisplayController永远不会被Angularjs解析,因此永远不会变成真正的控制器。如果我这样定义它:

function XDisplayController($scope) {
    $scope.text = "blah blah";
    console.log("this never gets printed");
}

遗憾的是,它没有受到影响。

我如何让angularjs知道模板,理想情况下我如何让它继承父作用域,这样它的行为就像放在页面上一样,就好像是通过一个角度指令?

我怀疑它可能与$compile有关,但我无法让它发挥作用。

哦,我应该提一下,Polymer有lifecycle callbacks,这可能是调用链接angularjs代码的适当位置。

编辑:我尝试了CodeHater的代码,将element.contents()更改为element.context.impl,并出现以下错误:

An attempt was made to reference a Node in a context where it does not exist.

我认为这与Shadow DOM以及聚合物创建的标签如何具有自己的上下文有关。

2 个答案:

答案 0 :(得分:5)

不确定如何从Angular方面解决这个问题......

在Polymer元素中使用Angular

目前,<polymer-element>是一个与Angular不同的世界。因为Polymer从元素中的第一个<template>创建Shadow DOM,所以您看到的错误来自Angular的编译器,而不是在Shadow DOM中找到ng-controller。它期望在全球范围内解析和运行。 element.contents()的解决方法看起来很有趣,但该调用无法理解如何遍历Shadow DOM AFAICT。

在 Polymer中使用Angular 的另一个问题是每个都有自己的(相似的)数据绑定和表达式语法。如果您尝试混合匹配,这将产生冲突。

更多相关信息:https://groups.google.com/d/topic/polymer-dev/s_wH7gaCQZ0/discussion

在Angular应用内部使用Polymer元素

您应该能够创建一个Polymer元素,为其提供API,发布一些属性,并在Angular应用程序中重用它们。相反(在Polymer元素中使用Angular)是我提到的Shadow DOM问题的棘手b / c。

我没有试过这个,所以你可能会看到polyfills试图做他们的事情有些奇怪。聚合物 - &gt; Angular肯定会使用本机API。

构建基于组件的应用

所有这些都说,如果我们开始构建基于组件的应用程序,那么一切都将变得笨拙。您使用指令使用Angular编写组件; Polymer写入Web组件。在外面和它们和谐地使用它们它们是整个应用程序的分隔构建块。因此,不要为标记部分编写控制器,而是编写组件!


这种回应的道德:我会在Angular小组中询问他们希望支持Shadow DOM的情况:)

答案 1 :(得分:1)

我是Polymer的新手,但我会请你尝试这样的事情:

<x-display polymer-directive ng-repeat="p in people | filter:query" 
    title="{{ p.name }}" body="{{ p.body }}"></x-display>

指令:

app.directive('polymerDirective', function($compile, $timeout) {
    return {
        link : function(scope, element, attrs) {
            $compile(element.contents())(scope);

            /* if polymer dont render the template before 
               the directive is linked you can just delay 
               the compilation a bit */             
            $timeout(function(){
                $compile(element.contents())(scope);
            },1000);

        }
    };
});