2016-07-20 5 views
22

У меня есть родительский и дочерний компонент. Родительский компонент имеет index и передает его дочернему компоненту как @Input. Это значение index постоянно изменяется в родительском компоненте, а внутри моего дочернего компонента я хочу запускать функцию каждый раз, когда изменяется компонент родителя index. У этого есть компонент слайда, который постоянно меняет его. Как я могу это достичь? Я пробовал с приведенным ниже кодом (this.index.subscribe(() =>), но я получаю, что это не функция каждый раз, когда я пытаюсь инициализировать подписку.Angular2, подписавшийся на изменения в @Input в дочернем компоненте

РЕДАКТИРОВАТЬ: В шаблоне нет соответствующего кода, который может повлиять на него, поэтому он не предоставляется. ngOnChange, похоже, не работает, поскольку изменение происходит в директиве, в отличие от шаблона parent.

Ребенок:

import {Component, OnInit, ViewChild, Input} from '@angular/core'; 
import {Observable} from 'rxjs/Observable'; 

@Component({ 
    selector: "child", 
    templateUrl: "components/child/child.html", 
}) 

export class ChildComponent implements OnInit { 
    @Input() index: string; 
    currentIndex: any; 

    constructor() {} 

    ngOnInit() {} 

    ngOnChanges(){} 

    ngAfterViewInit() { 
     console.log("index " + this.index); 
     this.currentIndex = this.index.subscribe(() => { 
      console.log("index " + this.index); 
     }) 
    } 

    ngOnDestroy() { 
     this.currentIndex.unsubscribe(); 
    } 

} 

Родитель:

import {Component, ElementRef, OnInit, ViewChild} from '@angular/core'; 
import {Page} from "ui/page"; 
import {ChildComponent} from '/components/child/child.component' 

@Component({ 
    selector: "parent", 
    template: "<child [index]="index"></child>", 
    directives: [ChildComponent] 
}) 

export class ParentComponent implements OnInit { 

    index: string = "0,1"; 

    constructor(private page: Page) { 
    } 



} 
+0

Прежде всего, шаблон 'ParentComponent' должен быть' template', а не 'templateUrl'. Кроме того, вы можете показать шаблон для 'ChildComponent'? – acdcjunior

+0

Эй, да, это просто из редактирования, который я сделал. в шаблоне «ChildComponent» нет ничего важного. Я не использую это значение в самом представлении. – bnussey

+0

'index' в' ParentComponent' ** - это 'string' **, а' ChildComponent' ожидает, что это будет 'Observable '. Так вы их используете? – acdcjunior

ответ

28

https://angular.io/docs/ts/latest/api/core/index/Input-var.html

Цитирую:

Angular automatically updates data-bound properties during change detection.

Если вам нужно выполнить некоторую обработку на входе, посмотрите на get и set. https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter

Из документации, вот пример.

import { Component, Input } from '@angular/core'; 
@Component({ 
    selector: 'name-child', 
    template: ` 
    <h3>"{{name}}"</h3> 
    ` 
}) 
export class NameChildComponent { 
    _name: string = '<no name set>'; 
    @Input() 
    set name(name: string) { 
    this._name = (name && name.trim()) || '<no name set>'; 
    } 
    get name() { return this._name; } 
} 

Вам не нужно использовать наблюдаемый.

+1

Иногда вы хотите повторно запускать метод вашего компонента после изменения любого ввода ... затем используя Я думаю, 'ngOnChanges()' намного проще, чем запускать этот метод в каждом наборе каждого входа. –

7

ngOnChange вызывается каждый раз, когда изменяется входных параметров. Вы даже имеете его в Child компонента, но он не реализован правильно:

ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { 
    // check the object "changes" for new data 
} 

Подробнее: https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#onchanges

Update: index в родительском компоненте является string. По какой-то причине в дочернем компоненте он стал Observable.

+0

Спасибо за ваш ответ. Можете ли вы посоветовать, как правильно его реализовать, пожалуйста, более подробно? – bnussey

+0

Кроме того, я не думаю, что это работает как параметр, который не изменяется на лицевой стороне, его изменение методом внутри самого родителя. Когда значение изменяется, я не получаю ни одного из журналов консоли. – bnussey

+0

Я могу подтвердить, что это не работает даже с правильной реализацией. – bnussey

12

Как уже упоминалось в другом ответе, вы можете использовать крючок для жизни . От Angular`s documentation:

ngOnChanges: Respond after Angular sets a data-bound input property. The method receives a changes object of current and previous values.

Проверьте пример ниже, чтобы увидеть, как вы можете использовать его:

import { Component, Input } from '@angular/core'; 

@Component({ 
    selector: 'child', 
    template: ` 
    Value: 
    <span>{{ value }}</span> 
    <br /> 
    <br /> 
    Number of changes: {{ numberOfChanges }} 
    ` 
}) 
export class ChildComponent { 
    @Input() value: any; 

    private numberOfChanges: number = 0; 

    ngOnChanges() { 
    this.numberOfChanges++; 
    } 
} 

Plunker: http://plnkr.co/edit/XjD1jjCnqiFdbhpTibIe

+0

Эй, спасибо за ваш ответ. Я думаю, что этот вопрос здесь состоит в том, что {index} не обновляется в шаблоне, он обновляется в директиве .. поэтому это событие никогда не запускается. Это не работает. – bnussey

+0

Какую директиву вы подразумеваете под обновлением индекса? –

+0

Пожалуйста, проверьте контекст внутри 'SlidesXml.on (« start », (event) => {...}' event –