bri*_*anv 5 angular2-directives angular
根据我对Angular 2的理解,ViewChildren装饰器允许Component获取其他组件或指令的查询。当我知道组件的特定类型时,我可以在Typescript中使用它,但是QueryList当我只知道组件的接口时,我希望能够得到一个。这样,我可以遍历视图组件。
例如,在组件中,我可能有:
@ViewChildren(Box) shapes: QueryList<Box>;
Run Code Online (Sandbox Code Playgroud)
其中Box是具体的TypeScript类。我想拥有的是:
@ViewChildren(IShape) shapes: QueryList<IShape>;
Run Code Online (Sandbox Code Playgroud)
IShapeBox或其他组件可以实现的接口在哪里。这样,视图可以非常动态,并且我的代码仍然可以工作。有没有建议的方法来解决这个问题?
不,接口信息在运行时不存在,因此不能用于查询实现特定接口的不同组件。
仅支持单一类型或模板变量列表,例如
@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>
Run Code Online (Sandbox Code Playgroud)
将产生 5 条参考文献children
实际上,有一种方法可以执行您尝试执行的操作,尽管可能不使用Typescript接口,因为GünterZöchbauer正确地认为,一旦将代码转换为javascript,它们就不会存在。
但是,您可以使用父类。父级可能是抽象类。现在,我考虑了一下,如果将接口转换为运行时名称空间(如果我不知道它们是不是),它们也应该也可以工作。
@Component({
selector: 'square',
providers: [provide(Shape, useExisting: forwardRef( ()=>Square )]
})
class Square extends Shape {}
Run Code Online (Sandbox Code Playgroud)
请参阅此讨论。
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 = {}));
Run Code Online (Sandbox Code Playgroud)
chart-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 = {}));
Run Code Online (Sandbox Code Playgroud)
chart-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 = {}));
Run Code Online (Sandbox Code Playgroud)
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 = {}));
Run Code Online (Sandbox Code Playgroud)
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>
Run Code Online (Sandbox Code Playgroud)
现在,在es5 javascript中,实际上没有必要扩展Renderable类以使其起作用。此外,您可以在提供程序列表中放置多个提供程序,从而可以查询您的组件或指令以获得我的多个令牌。因此,您可以说您可以以经典的javascript方式为实现ViewChild选择而“实现”几个“接口”,但实际上并没有任何保证。
| 归档时间: |
|
| 查看次数: |
3852 次 |
| 最近记录: |