4

我有一个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 了解模板,理想情况下,我将如何使其继承父范围,以便它的行为就像被放置在页面上一样,就像被 angular 指令一样?

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

哦,我应该提到 Polymer 有生命周期回调,这可能是调用任何链接 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 以及聚合物创建的标签如何拥有自己的上下文有关。

4

2 回答 2

5

不知道如何从Angular方面解决这个问题......

在 Polymer 元素中使用 Angular

目前,<polymer-element>是一个与 Angular 不同的世界。因为 Polymer 从<template>元素中的第一个元素创建 Shadow DOM,所以您看到的错误来自 Angular 的编译器没有ng-controller在 Shadow DOM 中找到。它期望在全局上下文中解析和运行。解决方法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 问题更棘手。

我还没有尝试过,所以你可能会看到 polyfills 尝试做他们的事情时有些奇怪。Polymer -> Angular 肯定会与原生 API 一起工作。

构建基于组件的应用程序

综上所述,如果我们开始构建基于组件的应用程序,一切都会变得很糟糕。您使用指令来使用 Angular 编写组件;用于编写 Web 组件的聚合物。在外部 b/c 上和谐地使用它们,它们是整个应用程序的分隔构建块。因此,不要为标记部分编写控制器,而是编写组件!


这个回应的寓意:我会在Angular小组中询问他们何时希望支持Shadow DOM :)

于 2013-10-01T15:19:30.373 回答
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);

        }
    };
});
于 2013-09-27T11:05:41.297 回答