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

时间:2015-12-10 11:42:55

标签: angular

我在父组件中有一个可能被子更改的变量,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");
    }
}

5 个答案:

答案 0 :(得分:63)

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

在父母的模板中:

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

在孩子身上:

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

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

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

这个Plunker shows a working example,父组件和子组件中的按钮都修改了共享列表。

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

如果要共享基本类型(即字符串,数字,布尔值),可以将其放入数组或对象(即将其放在引用类型中),或者可以emit()每当原始值发生变化时,来自子节点的事件(即,父节点监听自定义事件,并且子节点将具有EventEmitter输出属性。有关详细信息,请参阅@ kit的答案。)

更新 2015/12/22:Structural Directives指南中的heavy-loader示例使用了我上面介绍的技术。主/父组件具有绑定到子组件的logs数组属性。子组件push()到该数组上,父组件显示该数组。

答案 1 :(得分:15)

像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>

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

答案 2 :(得分:9)

你可以这样做 在父组件中声明:

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

答案 3 :(得分:3)

基本上,您无法直接从父级访问变量。你通过事件来做到这一点。组件的输出属性对此负责。我建议阅读https://angular.io/docs/ts/latest/guide/template-syntax.html#input-and-output-properties

答案 4 :(得分:2)

关于此主题的Angular2文档中的主要文章是:

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

它涵盖以下内容:

  • 使用输入绑定将数据从父级传递给子级

  • 使用setter拦截输入属性更改

  • 使用ngOnChanges

  • 拦截输入属性更改
  • 家长侦听子事件

  • 家长通过本地变量与孩子互动

  • Parent调用ViewChild

  • 家长和孩子通过服务沟通