当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《Angular2:子组件访问父类变量/函数》经验,为你挑选了3个好方法。

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

import {Component, View} from 'angular2/core';

@Component({selector: 'parent'})
@View({
    directives: [Child],
    template: ``
})
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");
    }
}

Mark Rajcok.. 64

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

在父模板中:


在孩子:

@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示例使用了我上面介绍的技术.main/parent组件具有绑定到子组件的数组属性.子组件到该数组上,父组件显示该数组.logspush()



1> Mark Rajcok..:

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

在父模板中:


在孩子:

@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示例使用了我上面介绍的技术.main/parent组件具有绑定到子组件的数组属性.子组件到该数组上,父组件显示该数组.logspush()



2> jsgoupil..:

NgModel和NgForm有什么关系呢?您必须将父级注册为提供者,然后将父级加载到子级的构造函数中.

这样,你就不必把[sharedList]所有孩子都戴上.

// Parent.ts
export var parentProvider = {
    provide: Parent,
    useExisting: forwardRef(function () { return Parent; })
};

@Component({
    moduleId: module.id,
    selector: 'parent',
    template: '
', providers: [parentProvider] }) export class Parent { @Input() public sharedList = []; } // Child.ts @Component({ moduleId: module.id, selector: 'child', template: '
child
' }) export class Child { constructor(private parent: Parent) { parent.sharedList.push('Me.'); } }

那你的HTML


    
    

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



3> FRL..:

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

get self(): ParenComponentClass {
        return this;
    }

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

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

get parent(): ParenComponentClass {
    return this._parent;
}

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


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

this.parent

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有