Angular 2,如何将选项从父组件传递到子组件?

时间:2016-02-26 19:09:13

标签: javascript angular

我一直在寻找解决方案。我尝试过@Input,@ Query,dynamicContentLoader,@ Inject,@ Inject(forwardRef(()但是还没有能够解决这个问题的一堆不同的东西。

我的示例结构:

parent.ts

import {Component} from 'angular2/core';

@Component({
    selector   : 'my-app',
    directives : [Child],
    template   : `<parent-component></parent-component>`
})

export class Parent
{
    private options:any;

    constructor()
    {
        this.options = {parentThing:true};
    }
}

child.ts

import {Component} from 'angular2/core';

@Component({
    selector   : 'parent-component',
    template   : `<child-component></child-component>`
})

export class Child
{
    constructor(private options:any) <- maybe I can pass them in here somehow?
    {
        // what I am trying to do is get options from
        // the parent component at this point
        // but I am not sure how to do this with Angular 2
        console.log(options) <- this should come from the parent

        // how can I get parent options here?
        // {parentThing:true}
    }
}

这是我在DOM中的当前HTML输出,因此这部分按预期工作

<parent-component>
   <child-component></child-component>
</parent-component>

问题摘要:

如何将选项从父组件传递到子组件并在子构造函数中提供这些选项?

2 个答案:

答案 0 :(得分:6)

父对子是最简单的形式,但它在构造函数中不可用,仅在ngOnInit()(或更高版本)中。

这只需要子组件中的@Input() someField;并使用绑定,这可以从父级传递给子级。父项中的更新将在子项中更新(而不是其他方向)

@Component({
  selector: 'child-component',
  template'<div>someValueFromParent: {{someValueFromParent}}</div>'
})  
class ChildComponent {
  @Input() someValueFromParent:string;

  ngOnInit() {
    console.log(this.someValue);
  }
}

@Component({
  selector: 'parent-component',
  template: '<child-component [someValueFromParent]="someValue"></child-component>'
})
class ParentComponent {
  someValue:string = 'abc';
}

让它在构造函数中可用使用共享服务。共享服务被注入到两个组件的构造函数中。要使注入工作,服务需要在父组件中或以上注册,而不是在子组件中注册。这样两者都获得相同的实例。 在父级中设置一个值并在客户端中读取它。

@Injectable()
class SharedService {
  someValue:string;
}

@Component({
  selector: 'child-component',
  template: '<div>someValueFromParent: {{someValueFromParent}}</div>'
})  
class ChildComponent {
  constructor(private sharedService:SharedService) {
    this.someValue = sharedService.someValue;
  }
  someValue:string = 'abc';
}

@Component({
  selector: 'parent-component',
  providers: [SharedService],
  template: '<child-component></child-component>'
})
class ParentComponent {
  constructor(private sharedService:SharedService) {
    sharedService.someValue = this.someValue;
  }
  someValue:string = 'abc';
}

更新

没有太大区别。对于DI,只能使用构造函数。如果你想要注入的东西,它必须通过构造函数。当进行额外的初始化(如正在处理的绑定)时,Angular会调用ngOnInit()。例如,如果您进行网络调用,那么如果您在ngOnInit中的构造函数中执行此操作并不重要,因为无论如何都会调度服务器(异步)。当前同步任务完成后,JavaScript将查找下一个计划任务并对其进行处理(依此类推)。因此,无论您将它放在何处,都可能在ngOnInit()之后实际发送构造函数中启动的服务器调用。

答案 1 :(得分:1)

您可以使用@Input参数:

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

@Component({
  selector   : 'parent-component',
  template   : `<child-component></child-component>`
})
export class Child {
  @Input()
  options:any;

  ngOnInit() {
    console.log(this.options);
  }
}

请注意,options的值在ngOnInit中可用,而不在构造函数中。有关更多详细信息,请查看组件生命周期挂钩:

并提供如下所述的选项:

import {Component} from 'angular2/core';

@Component({
  selector   : 'my-app',
  directives : [Child],
  template   : `<parent-component [options]="options"></parent-component>`
})
export class Parent {
  private options:any;

  constructor() {
    this.options = {parentThing:true};
  }
}

如果要实现自定义事件:child触发事件并通知父注册。使用@Output