Подтвердить что ты не робот

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");
    }
}
4b9b3361

Ответ 1

Если вы используете привязку данных свойства ввода со ссылочным типом JavaScript (например, Object, Array, Date и т.д.), то родительский и дочерний будут иметь ссылку на один и тот же/один объект. Любые изменения, внесенные в общий объект, будут видны как родителям, так и дочерним.

В родительском шаблоне:

<child [aList]="sharedList"></child>

У ребенка:

@Input() aList;
...
updateList() {
    this.aList.push('child');
}

Если вы хотите добавить элементы в список при построении дочернего элемента, используйте ngOnInit() (а не конструктор(), поскольку свойства данных не инициализированы в этой точке):

ngOnInit() {
    this.aList.push('child1')
}

Этот Plunker показывает рабочий пример с кнопками в родительском и дочернем компонентах, которые изменяют общий список.

Обратите внимание, что в случае ребенка вы не должны переназначать ссылку. Например, не делайте этого в дочернем элементе: this.aList = someNewArray; Если вы это сделаете, то родительский и дочерний компоненты будут иметь ссылки на два разных массива.

Если вы хотите поделиться примитивным типом (т.е. строка, число, логическое), вы можете поместить его в массив или объект (т.е. помещать его внутри ссылочного типа) или вы могли бы emit() событие от ребенка, когда изменяется примитивное значение (т.е. родительский прослушивает настраиваемое событие, а у ребенка будет свойство вывода EventEmitter. См. ответ @kit для получения дополнительной информации.)

Обновить 2015/12/22: пример heavy-loader в Структурные директивы использует технику я представленных выше. Основной/родительский компонент имеет свойство массива logs, связанное с дочерними компонентами. Детальные компоненты push() на этот массив, а родительский компонент отображает массив.

Ответ 2

Как насчет небольшого обмана, как 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>

Ответ 4

Вы можете сделать это В родительском компоненте объявите:

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

Ответ 5

Основная статья в документации Angular2 по этому вопросу:

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child

Он охватывает следующее:

  • Передача данных от родителя к дочерней с привязкой ввода

  • Переключить свойства ввода с помощью setter

  • Изменение свойств входных данных с помощью ngOnChanges

  • Родитель слушает дочернее событие

  • Родитель взаимодействует с дочерним элементом через локальную переменную

  • Родитель вызывает ViewChild

  • Родитель и дети общаются через службу