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");
}
}
674   5  

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

    Ничего не найдено.