Как предоставить модель родителя для динамически загруженного дочернего компонента в angular 2?

0

У меня есть много директив, построенных в приложении 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.

Теги:
angular
angular2-template

2 ответа

0

Для общения с компонентами, добавленными 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 {
  ...
}

Пример Plunker

  • 0
    Я обновил свой plunkr: plnkr.co/edit/fHD19h2hQHYJDy5KNIGD?p=preview Проблема в том, что я все еще не получаю двухстороннюю привязку данных. Документы предполагают, что использование массива провайдеров приведет ко второму экземпляру: angular.io/docs/ts/latest/tutorial/… По сути, я хочу, чтобы модель appcomponent и модель InputCmp были одной и той же моделью и соответственно обновляли друг друга. Вы видите, что я делаю не так?
  • 0
    Проблема в том, что вы передаете примитивные значения динамически загружаемому компоненту. Примитивные значения копируются, и ссылка на исходную модель теряется. Если вы изменяете его на объекты, он работает как положено plnkr.co/edit/FVxdZvxCsKVbvXZ7T8F1?p=preview
Показать ещё 1 комментарий
0

Причина в том, что вы забыли скобки []:

[model]="model.firstName"

Если мы забудем скобки, Angular обрабатывает строку как константу и инициализирует свойство target этой строкой. Он не оценивает строку!

см. doc, plunkr

Предполагая, что вы не можете изменять шаблоны, нет никаких чистых способов выполнения ваших требований. Я бы не рекомендовал его использовать, но мне захотелось воспользоваться библиотекой 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);
  • 0
    Боюсь, это может быть моим лучшим выбором. Однако я не забыл скобки. Я попросил решение, которое не требовало от меня изменения синтаксиса существующего шаблона. В идеале я хотел бы абстрагироваться от этого в новой версии компонента, который я обновляю, чтобы использовать Angular 2. Есть ли какой-либо другой способ передачи модели из родительского компонента в дочерний компонент?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню