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