Angular2: дочерний компонент доступ к родительской переменной класса / функции
У меня есть переменная в Родительском компоненте, которая может быть изменена дочерним элементом, родитель будет использовать эту переменную в представлении и, следовательно, должен распространять изменения.
import {Component, View} from 'angular2/core';
@Component({selector: 'parent'})
@View({
directives: [Child],
template: `<childcomp></childcomp>`
})
class Parent {
public sharedList = new Array();
constructor() {
}
}
@Component({selector: 'child'})
@View({template: `...`})
class Child {
constructor() {
//access 'sharedList' from parent and set values
sharedList.push("1");
sharedList.push("2");
sharedList.push("3");
sharedList.push("4");
}
}
5 ответов:
если вы используете привязку данных входных свойств с типом ссылки JavaScript (например, объект, массив, дата и т. д.), то родитель и ребенок будут иметь ссылку на один и тот же/один объект. Любые изменения, внесенные в общий объект, будут видны как родителю, так и ребенку.
в Родительском шаблоне:
<child [aList]="sharedList"></child>ребенок:
@Input() aList; ... updateList() { this.aList.push('child'); }если вы хотите добавить элементы в список на строительство ребенка, используйте
ngOnInit()hook (не конструктор (), так как свойства с привязкой к данным не инициализируются в этот момент):ngOnInit() { this.aList.push('child1') }этой Plunker показывает рабочий пример, с кнопками в Родительском и дочернем компоненте, которые оба изменяют общий список.
обратите внимание, что в ребенке вы не должны переназначать ссылку. Например, не делайте этого в ребенке:
this.aList = someNewArray;если вы это сделаете, то Родительский и дочерний компоненты будут иметь ссылки на два разные массивы.если вы хотите поделиться примитивным типом (т. е. строкой, числом, логическим), вы можете поместить его в массив или объект (т. е. поместить его в ссылочный тип), или вы можете
emit()событие от ребенка всякий раз, когда изменяется примитивное значение (т. е. родитель прослушивает пользовательское событие, а у ребенка будетEventEmitterвыходное свойство. См. ответ @kit для получения дополнительной информации.)обновление 2015/12/22: the
heavy-loaderпример в Структурные Директивы руководство использует технику, которую я представил выше. Основной / родительский компонент имеетlogsсвойство массива, привязанное к дочерним компонентам. Дочерние компонентыpush()на этот массив, и родительский компонент отображает массив.
как насчет небольшого обмана, как NgModel делает с NgForm? Вы должны зарегистрировать своего родителя в качестве поставщика, а затем загрузить своего родителя в конструктор ребенка.
таким образом, вы не должны положить
[sharedList]на всех своих детей.// Parent.ts export var parentProvider = { provide: Parent, useExisting: forwardRef(function () { return Parent; }) }; @Component({ moduleId: module.id, selector: 'parent', template: '<div><ng-content></ng-content></div>', providers: [parentProvider] }) export class Parent { @Input() public sharedList = []; } // Child.ts @Component({ moduleId: module.id, selector: 'child', template: '<div>child</div>' }) export class Child { constructor(private parent: Parent) { parent.sharedList.push('Me.'); } }тогда ваш HTML
<parent [sharedList]="myArray"> <child></child> <child></child> </parent>вы можете найти дополнительную информацию по этому вопросу в угловой документации: https://angular.io/guide/dependency-injection-in-action#find-a-parent-component-by-injection
вы можете сделать это В Родительском компоненте объявите:
get self(): ParenComponentClass { return this; }в дочернем компоненте, после включения импорта ParenComponentClass, объявите:
private _parent: ParenComponentClass ; @Input() set parent(value: ParenComponentClass ) { this._parent = value; } get parent(): ParenComponentClass { return this._parent; }тогда в шаблоне родителя вы можете сделать
<childselector [parent]="self"></childselector>теперь от ребенка, вы можете получить доступ к открытым свойствам и методам родительского используя
this.parent
в основном вы не можете получить доступ к переменным из родителей напрямую. Вы делаете это по событиям. За это отвечает выходное свойство компонента. Я бы предложил почитать https://angular.io/docs/ts/latest/guide/template-syntax.html#input-and-output-properties
основная статья в документации Angular2 по этому вопросу:
https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child
Он охватывает следующее:
передача данных от родителя к ребенку с привязкой ввода
Перехват изменения входных свойств с помощью сеттера
перехватить изменения входных свойств с помощью ngOnChanges
родитель слушает дочернее событие
родитель взаимодействует с ребенком через локальную переменную
родитель вызывает ViewChild
родители и дети общаются через сервис
Comments