我在父组件中有一个可能被子更改的变量,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");
}
}
答案 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
家长和孩子通过服务沟通