Angular2:子组件访问父类变量/函数
我在父组件中有一个可能被子组件更改的变量,父组件将在视图中使用该变量,因此必须传播更改Angular2:子组件访问父类变量/函数,angular,Angular,我在父组件中有一个可能被子组件更改的变量,父组件将在视图中使用该变量,因此必须传播更改 import {Component, View} from 'angular2/core'; @Component({selector: 'parent'}) @View({ directives: [Child], template: `<childcomp></childcomp>` }) class Parent { public sharedList
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");
}
}
从'angular2/core'导入{Component,View};
@组件({选择器:'父'})
@看法({
指令:[儿童],
模板:``
})
班级家长{
public sharedList=新数组();
构造函数(){
}
}
@组件({选择器:'子'})
@视图({模板:`…`})
班童{
构造函数(){
//从父级访问“sharedList”并设置值
共享列表推送(“1”);
共享列表推送(“2”);
共享列表推送(“3”);
共享列表推送(“4”);
}
}
基本上,您不能直接从父级访问变量。你可以通过事件来做到这一点。组件的输出属性对此负责。我建议阅读如果您将输入属性数据绑定与JavaScript引用类型(例如,对象、数组、日期等)一起使用,那么父对象和子对象都将具有对相同/一个对象的引用。您对共享对象所做的任何更改都将对父对象和子对象可见
在父级的模板中:
<child [aList]="sharedList"></child>
如果要在构造子项时将项添加到列表中,请使用钩子(而不是构造函数(),因为数据绑定属性在此点未初始化):
这样,父组件和子组件中的按钮都可以修改共享列表
注意,在子对象中,不能重新指定引用。例如,不要在子级中执行此操作:this.aList=someNewArray代码>如果这样做,那么父组件和子组件将分别引用两个不同的数组
如果要共享基元类型(即字符串、数字、布尔值),可以将其放入数组或对象中(即将其放入引用类型中),也可以在基元值更改时从子级发出事件(即,让父对象侦听自定义事件,子对象将具有EventEmitter
输出属性。有关更多信息,请参阅@kit的答案。)
更新2015/12/22:指南中的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.');
}
}
//Parent.ts
导出变量parentProvider={
提供:家长,
useExisting:forwardRef(函数(){return Parent;})
};
@组成部分({
moduleId:module.id,
选择器:'父',
模板:“”,
提供者:[父提供者]
})
导出类父类{
@输入()
公共共享列表=[];
}
//Child.ts
@组成部分({
moduleId:module.id,
选择器:'子',
模板:“孩子”
})
导出类子类{
构造函数(私有父级:父级){
parent.sharedList.push('Me');
}
}
然后是你的HTML
<parent [sharedList]="myArray">
<child></child>
<child></child>
</parent>
您可以在Angular2文档中找到关于这个主题的更多信息:Angular2文档中关于这个主题的主要文章是:
它包括以下内容:
- 使用输入绑定将数据从父级传递到子级
- 使用setter截取输入属性更改
- 使用ngOnChanges截取输入属性更改
- 父进程侦听子事件
- 父对象通过局部变量与子对象交互
- 父调用ViewChild
- 父母和子女通过服务进行沟通
你可以这样做
在父组件中声明:
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>
我不知道这种方法,但它不适用于字符串。@mark rajcok你能检查一下我的@kit吗,你的链接似乎是指向我的plunker的链接。但不管怎样……在父子之间共享这样的字符串是行不通的(在子->父方向)因为子项具有本地基元类型,而不是本地引用类型。对于基元类型,父项和子项都有自己的(字符串)副本--这就是JavaScript的工作方式……我们无法创建对基元类型的引用。虽然父级会强制将新字符串值下放到子级,但父级不会引用子级的字符串属性,因此不会注意到任何子级更改。请澄清:如果我想在子级和父级组件之间共享字符串变量,请使用g@Input,我只使用原始字符串new string(“myValue”)的包装器,一切正常。@user59442,使用您的方法,您如何更改子元素中的字符串值,并将其反映在父元素中?在模板HTML中使用指定子元素时,如何在父元素和子元素之间共享数据(第页)根据当前路线?我想知道我们是否应该开始标记Angular2“alpha”不同的解决方案,所以现在开始使用它的人不会感到困惑。这显然是与“@View”一起写的。想法?对我来说很有意义。我自己在看到这些答案时感到困惑,最终意识到它有很多倒退。虽然这不是官方文档,但我也发现这篇文章很有用:谢谢!只需要简单的答案提醒大家去看看ng2主站点上的输出:-足够简单。我想在这里留下这个链接:你对这个特殊问题有完整的解决方案吗?现在还不清楚发出一个事件在这里有什么帮助。这个“笨拙的”怎么样,或者它是否适合“角度的doi方式”
private _parent: ParenComponentClass ;
@Input() set parent(value: ParenComponentClass ) {
this._parent = value;
}
get parent(): ParenComponentClass {
return this._parent;
}
<childselector [parent]="self"></childselector>
this.parent