Can Decorator ViewChildren in Angular2 work with interfaces?

As I understand Angular 2, the decorator ViewChildrenallows the Component to receive a request for other components or directives. I can get this to work in Typescript when I know a specific Component Type, but I would like to be able to get QueryListit when I just know the component interface. That way, I can iterate through the components of the view.

For example, in a component, I can have this:

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

where Box is a specific Typescript class. I would like to have the following:

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

where IShapeis the interface Boxes or other components can implement. This way, the view can be very dynamic and my code will work. Is there a recommended way to handle this?

+3
source share
2 answers

No, interface information does not exist at run time and therefore cannot be used to query various components that implement a particular interface.

Only one type or list of template variables is supported, for example

@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>

will result in 5 links in children

+1
source

Actually there is a way to do something like what you are trying to do, although it might not be with Typescript interfaces, since Günter Zöchbauer is correct that they do not exist as such when the code is passed to javascript.

. , . , , , , , .

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

.

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

, es5, , . , .

, , , .

, , , . , . , , es5, . app.Renderable , NgModule.

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, Renderable, . , , , . , , "" "" ViewChild javascript , .

+1

All Articles