На самом деле есть способ сделать что-то похожее на то, что вы пытаетесь сделать, хотя, возможно, и не с интерфейсами Typescript, поскольку Гюнтер Цохбауэр прав в том, что они не существуют как таковые после переноса кода в 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.
визуализируемый.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 = {}));
панель инструментов.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 = {}));
панель инструментов.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 es5, фактически нет необходимости расширять класс Renderable, чтобы это работало. Кроме того, вы можете поместить более одного провайдера в свой список провайдеров и, таким образом, разрешить запрашивать ваш компонент или директиву для моих нескольких токенов. Таким образом, вы можете сказать, что можете «реализовать» несколько «интерфейсов» для целей выбора ViewChild в классическом стиле javascript, на самом деле ничего не гарантировано.
person
Kyle Zimmer
schedule
14.12.2016