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>

これはすべてかなりクールです。1 つの例外を除いて、期待どおりにまったく同じように動作し<x-display>ます。各人に 1 つずつ、大量のタグを配置し、それらに正しい値を入力します。オカレンスがフラッシュアップしないPolymerように、値をデフォルトでnullにする呼び出しを行いますが、それ以外は素晴らしくシンプルです。{{ p.value }}

問題は、ネストXDisplayControllerされたものがAngularjsによって解析されないため、実際のコントローラーにならないことです。次のように定義した場合:

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

惜しくも手付かずのままです。

angularjs にテンプレートを認識させるにはどうすればよいでしょうか。理想的には、親スコープを継承させて、Angular ディレクティブによってページに配置されたかのように動作させるにはどうすればよいでしょうか?

$compileと関係があるのではないかと思いますが、動作させることができません。

ああ、Polymer にはライフサイクル コールバックがあることに言及する必要があります。これは、angularjs コードをリンクするものを呼び出すのにおそらく適切な場所です。

編集: Element.contents() を element.context.impl に変更して CodeHater のコードを試したところ、次のエラーが発生しました。

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 を使用する場合のもう 1 つの落とし穴は、それぞれに独自の (類似した) データ バインディングと式の構文があることです。これを混ぜ合わせようとすると、衝突が発生します。

詳細: https://groups.google.com/d/topic/polymer-dev/s_wH7gaCQZ0/discussion

Angular アプリ内で Polymer 要素を使用する

Polymer 要素を作成し、それに API を与え、いくつかのプロパティを公開し、それらを Angular アプリで再利用できる必要があります。その逆 (Polymer 要素内で Angular を使用) は、私が言及した Shadow DOM の問題の b/c よりもトリッキーです。

私はこれを試していないので、ポリフィルが自分のことをしようとしていることに奇妙な点があるかもしれません。Polymer -> Angular は確実にネイティブ API で動作します。

コンポーネント ベースのアプリの構築

とはいえ、コンポーネントベースのアプリの構築を開始すると、すべてがうまくいかなくなります。ディレクティブを使用して、Angular を使用してコンポーネントを記述します。Web コンポーネントを作成する Polymer。それらは、アプリ全体の区画化された構成要素であるため、外側で調和して使用します。したがって、マークアップのセクションのコントローラーを作成する代わりに、コンポーネントを作成してください!


この回答の教訓: Shadow DOM をいつサポートする予定なのか、Angular グループに質問します :)

于 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 に答える