2016-03-29 28 views
3

我了解Angular 2的方式,ViewChildren修饰器允许组件获取其他组件或指令的查询。当我知道组件的具体类型时,我可以将它用于Typescript,但是当我刚刚知道组件的接口时,我希望能够获得QueryList。这样,我可以遍历视图组件。Angular2中的ViewChildren装饰器可以使用接口吗?

例如,在I成分可以具有这样的:

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

其中盒是一个具体的打字稿类。我想有是这样的:

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

其中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> 

将导致5个引用在children

1

其实也有办法做到像你正在尝试以模板变量列表尽管可能不能使用Typescript接口,但GünterZöchbauer是正确的,因为一旦代码被转换为javascript,它们就不存在。

但是,您可以使用父类。父母可能可能是一个抽象类。现在我想到了,如果接口被转换到运行时命名空间中,那么接口也应该工作,我不知道它们是否是。

@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 = {})); 

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> 

现在,在ES5 javascript,实际上没有必要扩展R为了实现这个目标,我们需要一个强大的课程此外,您可以将多个提供程序放在您的提供程序列表中,从而允许为您的组件或指令查询我的多个标记。因此,你可以说你可以实现几个“界面”的ViewChild选择的目的在经典的JavaScript方式没有任何实际保证。

相关问题