首页 文章

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

提问于
浏览
2

我一直在寻找解决方案 . 我从@ Input,@ Query,dynamicContentLoader,@ Inject,@ Inject(forwardRef(())尝试了很多不同的东西,但还没有想到这个 .

My Example Structure:

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>

Question Summarized:

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

2 回答

  • 1

    父对子是最简单的形式,但它在构造函数中不可用,仅在 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';
    }
    

    update

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

  • 5

    您可以使用 @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};
      }
    }
    

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

相关问题