2016-03-29 4 views
3

角2を理解する方法では、ViewChildrenデコレータは、コンポーネントが他のコンポーネントまたはディレクティブのクエリを取得できるようにします。私はTypescriptでコンポーネントの特定の型を知っているときにこれを動作させることができますが、私はコンポーネントのインターフェイスを知っているときにQueryListを取得したいと考えています。このようにして、ビューコンポーネントを反復処理できます。Angular2のViewChildrenデコレータはインターフェイスで動作できますか?

例えば、成分に私はこれを有していてもよい:

@ViewChildren(Box) shapes: QueryList<Box>; 

をボックスコンクリート活字体のクラスです。 IShapeがボックスまたは他のコンポーネントが実装可能インターフェースである

@ViewChildren(IShape) shapes: QueryList<IShape>; 

:私は何がしたいことはこれです。そうすれば、ビューは非常に動的になり、私のコードは引き続き機能します。これを処理するための推奨される方法はありますか?

+0

共通のスーパークラスhttps://github.com/angular/angular/issues/8580#issuecomment-218525425を照会することは可能です。 –

答えて

1

いいえ、インターフェイス情報は実行時に存在しないため、特定のインターフェイスを実装するさまざまなコンポーネントのクエリには使用できません。

サポートは、単一のタイプまたは

などのテンプレート変数のリスト
@ViewChildren('a,b,c,d') children; 

<div #a>a</div> 
<div #b>a</div> 
<div #c>a</div> 

<div #d>a</div> 
<div #d>a</div> 

<div #e>a</div> 

が実際にあなたがしようとしているもののような何かをする方法がありchildren

1

で5つの参考文献につながるですGinterZöchbauerは、コードがJavaScriptに変換された後には存在しないという点で正しいので、Typescriptインターフェースではないかもしれません。

ただし、親クラスを使用できます。親はおそらく抽象クラスである可能性があります。私はそれについて考えているので、インタフェースが実行時名前空間に移植されていればインタフェースも機能するはずです。

@Component({ 
    selector: 'square', 
    providers: [provide(Shape, useExisting: forwardRef(()=>Square)] 
}) 
class Square extends Shape {} 

この説明を参照してください。

https://github.com/angular/angular/issues/8580

今、私は私のようなES5を使用してそれらのため、そしてより徹底したユースケースのデモンストレーションのために以下の私自身の例を残したいです。この例が無関係なことなく全体として意味をなされるように、余分なディテールのバランスを取ろうとしました。

トピックを削除するために私を投票するつもりなら、ちょうどここで読むことをやめてください。

ダッシュボードコンポーネントでカスタムリサイズロジックを行う必要がありました。親ダッシュボードコンポーネントでカスタムリサイズロジックを実行した後にのみ、さまざまなタイプのチャートディレクティブを再レンダリングする必要がありました。一部のチャートは実際にはコンポーネントであり、問​​題はありませんでした。 es5で以下のパターンを動作させるために必要なものはすべて標準です。 NgModuleに与えられたプロバイダのリストにapp.Renderableを含める必要はありません。

renderable.class.js

(function(app) { 
    app.Renderable = ng.core.Class({ 
     constructor : [function Renderable() {}], 
     render : function() {} 
    }); 
})(window.app || (window.app = {})); 

チャートone.directive。JS

(function(app) { 
    app.ChartOneDirective = ng.core.Directive({ 
     selector : 'canvas[chart-one]', 
     inputs : ['config:chart-one'], 
     providers : [{ 
      provide: app.Renderable, 
      useExisting: ng.core.forwardRef(function(){ 
       return app.ChartOneDirective; 
      }), 
     }] 
    }).Class({ 
     extends : app.Renderable, 
     constructor : [/* injections */ function ChartOneDirective(/* injections */) { 
      // do stuff 
     }], 

     // other methods 

     render : function() { 
      // render the chart 
     } 
    }); 
})(window.app || (window.app = {})); 

チャートtwo.directive.js

(function(app) { 
    app.ChartTwoDirective = ng.core.Directive({ 
     selector : 'canvas[chart-two]', 
     inputs : ['config:chart-two'], 
     providers : [{ 
      provide: app.Renderable, 
      useExisting: ng.core.forwardRef(function(){ 
       return app.ChartTwoDirective; 
      }), 
     }] 
    }).Class({ 
     extends : app.Renderable, 
     constructor : [/* injections */ function ChartTwoDirective(/* injections */) { 
      // do stuff 
     }], 

     // other methods 

     render : function() { 
      // render the chart 
     } 
    }); 
})(window.app || (window.app = {})); 

dashboard.component.js

(function(app) { 
    app.DashboardComponent = ng.core.Component({ 
     selector : 'dashboard-component', 
     templateUrl : 'components/dashboard/dashboard.component.html', 
     host : { 
      '(window.resize)' : 'rerender()', 
     }, 
     queries : { 
      renderables : new ng.core.ViewChildren(app.Renderable), 
      // other view children for resizing purposes 
     } 
    }).Class({ 
     constructor : [/* injections */ function DashboardComponent(/* injections */) { 
      // do stuff 
     }], 

     resize : function() { 
      // do custom sizing of things within the dom 
     }, 

     // other methods 

     rerender : function() { 
      this.resize(); 
      this.renderables.forEach(function(r){ 
       r.render(); 
      }); 
     } 
    }); 
})(window.app || (window.app = {})); 

ES5で今dashboard.component.html

<div #sizeMe> 
    <div class='canvas-wrapper'><canvas [chart-one]></canvas></div> 
    <div class='canvas-wrapper'><canvas [chart-two]></canvas></div> 
    <div class='canvas-wrapper'><canvas [chart-one]></canvas></div> 

    <div #sizeMeToo> 
     <div class='canvas-wrapper'><canvas [chart-two]></canvas></div> 
     <div class='canvas-wrapper'><canvas [chart-one]></canvas></div> 
    </div> 
</div> 

、 javascriptでは、実際にはRを拡張する必要はありませんこれが機能するためには、エンジェルクラスが必要です。さらに、プロバイダリストに複数のプロバイダを置くことができるため、複数のトークンに対してコンポーネントまたはディレクティブを照会することができます。したがって、実際には保証されていない古典的なjavascriptの方法でViewChildの選択の目的でいくつかの「インターフェース」を「実装」できると言うことができます。

関連する問題