Angular2:子组件访问父类变量/函数

Kha*_*led 64 angular

我在父组件中有一个可能由child更改的变量,parent将在视图中使用此变量,因此必须传播更改.

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*cok 64

如果您使用带有JavaScript引用类型的输入属性数据绑定(例如,Object,Array,Date等),那么父级和子级都将引用相同/一个对象.您对共享对象所做的任何更改都将对父级和子级都可见.

在父模板中:

<child [aList]="sharedList"></child>
Run Code Online (Sandbox Code Playgroud)

在孩子:

@Input() aList;
...
updateList() {
    this.aList.push('child');
}
Run Code Online (Sandbox Code Playgroud)

如果要在构造子项时将项添加到列表中,请使用ngOnInit()钩子(而不是构造函数(),因为此时未初始化数据绑定属性):

ngOnInit() {
    this.aList.push('child1')
}
Run Code Online (Sandbox Code Playgroud)

这个Plunker显示了一个工作示例,父组件和子组件中的按钮都修改了共享列表.

请注意,在孩子中,您不得重新分配参考.例如,不要在子进程中执行此操作: this.aList = someNewArray; 如果这样做,那么父组件和子组件将分别引用两个不同的数组.

如果你想共享一个基本类型(即字符串,数字,布尔值),你可以将它放入一个数组或一个对象(即,将它放在一个引用类型中),或者你可以emit()在每个基元时从子进程发出一个事件值更改(即,让父级侦听自定义事件,并且子级将具有EventEmitter输出属性.有关详细信息,请参阅@ kit的答案.)

更新 2015/12/22:结构指令指南中的heavy-loader示例使用了我上面介绍的技术.main/parent组件具有绑定到子组件的数组属性.子组件到该数组上,父组件显示该数组.logspush()


jsg*_*pil 16

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.');
    }
}
Run Code Online (Sandbox Code Playgroud)

那你的HTML

<parent [sharedList]="myArray">
    <child></child>
    <child></child>
</parent>
Run Code Online (Sandbox Code Playgroud)

您可以在Angular文档中找到有关该主题的更多信息:https://angular.io/guide/dependency-injection-in-action#find-a-parent-component-by-injection


FRL*_*FRL 9

您可以在父组件声明中执行此操作:

get self(): ParenComponentClass {
        return this;
    }
Run Code Online (Sandbox Code Playgroud)

在子组件中,在包含ParenComponentClass的导入之后,声明:

private _parent: ParenComponentClass ;
@Input() set parent(value: ParenComponentClass ) {
    this._parent = value;
}

get parent(): ParenComponentClass {
    return this._parent;
}
Run Code Online (Sandbox Code Playgroud)

然后在父母的模板中你可以做

<childselector [parent]="self"></childselector>
Run Code Online (Sandbox Code Playgroud)

现在,从孩子可以访问父母使用的公共属性和方法

this.parent
Run Code Online (Sandbox Code Playgroud)