как инициировать изменения с помощью @input decorator angular 2

#angular #typescript

#angular #typescript

Вопрос:

У меня есть родительский компонент, у которого есть title поле. Это поле передается дочернему компоненту с помощью @input декоратора. В моем дочернем компоненте я добавил некоторую логику для манипулирования title значением, прежде чем показывать его в моем HTML.

Поскольку моя логика находится в ngInit цепочке дочернего компонента, только в первый раз title поле отражается правильно. Изменения, которые происходят с тех пор, не отражаются. Теперь я знаю, что это потому ngInit , что вызывается один раз, но как мне инициировать изменение от моего родителя к дочернему элементу, сообщив ему перепроверить значение?

РЕДАКТИРОВАТЬ Добавлен фрагмент кода

Компонент заголовка (дочерний)

 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>
  

Комментарии:

1. Предоставьте некоторый фрагмент кода или создайте plunker / jsfiddle.

Ответ №1:

Вы можете либо создать @Input() title: string | Array<any> сеттер, либо использовать ngOnChanges() вместо ngOnInit() . ngOnChanges() вызывается каждый раз @Input() при обновлении.

 @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;
    }
}
  

Комментарии:

1. Спасибо за ваш быстрый ответ. Оказывает ли установка @Input as set какое-либо влияние на производительность или оба метода работают одинаково? 🙂

2. Нет, использование его в качестве установщика не оказывает никакого влияния на производительность. Установщик вызывается только один раз каждый раз, когда обнаружение изменений распознает изменение в родительском headerTitle свойстве.

3. По какой-то сумасшедшей причине моя среда IDE (Sublime text 3) не распознает @Input set синтаксис. Помечает его красным:(

4. Извините, понятия не имею о TS с Sublime 3

5. Ну, я использовал этот ngOnChanges метод и его обнаружение изменений. Однако по какой-то странной причине он не перерисовывает его в слое представления (DOM), какие-либо подсказки, почему это может быть?