【问题标题】:how to trigger change with @input decorator angular 2如何使用@input decorator angular 2 触发更改
【发布时间】:2016-09-29 11:37:14
【问题描述】:

我有一个父组件,它有一个title 字段。使用 @input 装饰器将此字段传递给子组件。在我的子组件中,我添加了一些逻辑来操作 title 值,然后再将其显示在我的 HTML 中。

因为我的逻辑在子组件的ngInit钩子里,所以只有title字段第一次正确反映。从那时起发生的变化不会反映。现在我知道这是因为 ngInit 被调用了一次,但是我如何触发从我的父母到孩子的变化告诉它重新检查值?

编辑添加代码 sn-p

标头(子)组件

export class HeaderComponent implements OnInit {
@Input() title: string | Array<any>;

titleType = 'string';
tabletTitle: string | Array<any>;


constructor() { }

ngOnInit() {

    if ( typeof this.title == 'object' ) {
        this.titleType = 'array';

        // For tablet - only send the last most array item
        this.tabletTitle = [this.title[this.title.length - 1]];     // Has to be in the form of array (to be consistent with other orange header data type)
    } else {
        // Title is string - same for tablet
        this.tabletTitle = this.title;
    }

    // Temporary to show filter button on catalog page
    if ( this.page == 'catalog' ) {
        this.showFilterButton = true;
    }
}
}

标题模板

    <h1 *ngIf="titleType=='string'">{{title}}</h1>
    <h1 *ngIf="titleType=='array'">
        <ul class="header-breadcrumb">
            <template ngFor let-item [ngForOf]="title | keyValueObject">
                <li title="{{item.value['title']}}">
                    <a *ngIf="item.value['link']" [routerLink]="item.value['link']">{{item.value['title']}}</a>
                    <span *ngIf="!item.value['link']">{{item.value['title']}}</span>
                </li>
                <li *ngIf="!last" class="separator"></li>
            </template>
        </ul>
        <ul class="header-breadcrumb tablet">
            <li *ngFor="let item of tabletTitle | keyValueObject">
                <a *ngIf="item.value['link']" [routerLink]="item.value['link']">{{item.value['title']}}</a>
                <span *ngIf="!item.value['link']">{{item.value['title']}}</span>
            </li>
        </ul>
    </h1>

父组件

if ( this.parentCatId ) {
    // Push Parent Category name in header title
    this.headerTitle.push({title: 'Parent'});
}

if ( this.subCatId ) {          
    // Push Sub Category name in header title
    this.headerTitle.push({title: 'Child'});
}

父组件 HTML

<app-header [title]="headerTitle"></app-header>

【问题讨论】:

  • 提供一些代码 sn-p 或创建一个 plunker/jsfiddle。

标签: angular typescript


【解决方案1】:

您可以将@Input() title: string | Array&lt;any&gt; 设为setter,也可以使用ngOnChanges() 代替ngOnInit()。每次更新 @Input() 时都会调用 ngOnChanges()

@Input() set title(value: string | Array<any>) {
  ...
}

ngOnChanges() {

    if ( typeof this.title == 'object' ) {
        this.titleType = 'array';

        // For tablet - only send the last most array item
        this.tabletTitle = [this.title[this.title.length - 1]];     // Has to be in the form of array (to be consistent with other orange header data type)
    } else {
        // Title is string - same for tablet
        this.tabletTitle = this.title;
    }

    // Temporary to show filter button on catalog page
    if ( this.page == 'catalog' ) {
        this.showFilterButton = true;
    }
}

【讨论】:

  • 感谢您的快速回复。将@Input 设置为set 是否会对性能产生任何影响,或者两种方法的工作方式相同? :)
  • 不,将它作为设置器不会对性能产生任何影响。每次更改检测识别到父 headerTitle 属性上的更改时,setter 都会被调用一次。
  • 出于某种疯狂的原因,我的 IDE(Sublime text 3)无法识别 @Input set 语法。用红色标记:(
  • 抱歉,不知道 Sublime 3 的 TS
  • 好吧,我使用了ngOnChanges 方法及其检测变化。但是由于某些奇怪的原因,它没有在视图层 (DOM) 中重新渲染它,有什么线索可能会这样吗?
猜你喜欢
  • 2020-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-02
  • 2019-08-21
  • 2017-06-15
相关资源
最近更新 更多