Angular 组件构造函数被调用两次

Posted

技术标签:

【中文标题】Angular 组件构造函数被调用两次【英文标题】:Angular Component Constructor Called Twice 【发布时间】:2017-04-02 16:10:01 【问题描述】:

我是 Angular 的新手,遇到了一个子组件上的构造函数被调用两次的问题,第二次调用它是清除第一次设置的属性。

这是父组件:

@Component(
    selector: 'parent-item',
    templateUrl: '...',
    providers: [ItemService]
)
export class ParentItemComponent 
    public parentItemId;
    public model: ParentItem;

    constructor(itemService: ItemService, elm: ElementRef) 
        this.parentItemId = elm.nativeElement.getAttribute('parentItemId'); 
        itemService.getParentItem(this.parentItemId).subscribe(data => this.model = data);
    

并且在模板中引用了子组件:

<child-items [parentItemId]="parentItemId">Loading...</<child-items>

这是子组件:

@Component(
    selector: 'child-items',
    templateUrl: '...',
    providers: [ItemService]
)
export class ChildItemsComponent 
    @Input() public parentItemId: number;
    public items: Observable<ChildItem[]>;

    constructor(private itemService: ItemService) 
        console.log("constructor");
    

    ngOnInit() 
        if (this.parentItemId) 
            this.items = this.itemService.getChildItems(this.parentItemId);
          
        else 
            console.log("Parent Id not set!");
        
    

最后是子组件模板:

<tr *ngFor="let item of items | async">
    <td>...</td>
</tr>

子组件构造函数被调用了两次,第二次调用时 parentItemId 被设置为 null 并且 items 属性被清除。如果我硬编码 parentId 而不是使用输入,则数据会被正确接收并显示在模板中,但使用输入值,模板不会显示任何结果。

我创建了一个 plunker,它在此处显示相同的行为:http://embed.plnkr.co/xaJtfNgbWCUPap2RCJUA/

【问题讨论】:

&lt;child-items [parentItemId]="parentItemId"&gt;Loading...&lt;/&lt;child-items&gt;&lt;/&lt; 故意这样做的吗? 【参考方案1】:

您的问题是在 app.module 中您引导父组件和子组件:

bootstrap:    [ ParentItemComponent, ChildItemsComponent ]

必须是

  bootstrap:    [ ParentItemComponent]

【讨论】:

我在main.tsapp.module.ts 中都使用了platformBrowserDynamic().bootstrapModule(AppModule)。从app.module.ts 中删除该行使其适用于我的情况。【参考方案2】:

child-items 未正确关闭。可能是因为this error

这个

<child-items [parentItemId]="parentItemId">Loading...</<child-items>

应该是:

<child-items [parentItemId]="parentItemId">Loading...</child-items>

【讨论】:

以上是关于Angular 组件构造函数被调用两次的主要内容,如果未能解决你的问题,请参考以下文章

tomcat服务器启动,Filter 的构造函数被调用了两次,doFilter函数调用了一次,

为啥构造函数被调用两次

为啥析构函数被调用两次而构造函数只被调用一次?

如何在 Angular 2 中调用其构造函数之前将数据发送或绑定到子组件?

Angular 6订阅构造函数上的事件多次调用

为啥不应该在Angular中组件的构造函数中进行数据初始化?