У меня есть много директив, построенных в приложении Angular 1.x. Эти директивы используются различными внутренними приложениями в моей компании. Я бы хотел, чтобы эти приложения не нуждались в изменении своего кода, но вместо этого абстрактно объясняли многие из этих синтаксических изменений в моих директивах при обновлении до Angular 2.x. Например, допустим, что у меня есть следующая директива:
<my-directive
my-first-attribute="vm.someProperty"
my-second-attribute="vm.someFunction()"
></my-directive>
Предположим, я не могу изменить этот синтаксис с точки зрения родительского компонента. Эти атрибуты должны быть преобразованы в нечто вроде:
[myFirstAttribute]="vm.someProperty"
(click)="vm.someFunction()"
Раньше была функция компиляции, в которой я мог бы сделать многие из этих изменений шаблона перед связыванием. Теперь у меня есть моя функция конструктора, где я могу потянуть ElementRef
, а DynamicComponentLoader
Однако как я могу предоставить vm
моему динамически загруженному компоненту?
Я пробовал:
this._loader.loadIntoLocation(SubCmp, this._el, 'container')
.then((compRef:ComponentRef) => {
compRef.instance.vm = this.vm;
});
но компонент, который использует DynamicComponentLoader
сам, не знает о vm
. Я действительно не хочу менять синтаксис HTML, который вызывает компонент, который по очереди динамически загружает свои дочерние компоненты. Вот мой текущий plunkr, который использует Angular 2 beta 15.
Для общения с компонентами, добавленными DCL с использованием общей службы, как правило, это путь. Некоторый предок предоставляет услугу, а компонент, добавленный DCL, внедряет его
@Injectable()
class Model {
value:string = 'xxx';
}
export class InputCmp {
constructor(private model:Model){}
...
}
@Component({
selector: 'textbox',
...
providers: [Model]
})
export class Textbox implements OnInit {
...
}
Причина в том, что вы забыли скобки []
:
[model]="model.firstName"
Если мы забудем скобки, Angular обрабатывает строку как константу и инициализирует свойство target этой строкой. Он не оценивает строку!
Предполагая, что вы не можете изменять шаблоны, нет никаких чистых способов выполнения ваших требований. Я бы не рекомендовал его использовать, но мне захотелось воспользоваться библиотекой angular-expressions
, проверьте этот plunkr
Идея заключается в том, чтобы получить родительский контекст через иерархию инжектора и разборные выражения вручную.
//i don't fully understand why component index is 0
var context = injector.parent.getAt(0);
//create parser for this.model expression, i.e. 'model.firstName'
var evaluate = angularExpressions.compile(this.model);
//apply value from context
comp.model = evaluate(context);