2016-04-01 3 views
1

Детский компонент имеет два входных свойства, связанных с данными, один из типов string (inputVariable) и другого типа string[] (inputArray).Взаимодействие между компонентами в Угловом 2

import {Component, Inject, Input} from 'angular2/core'; 
@Component(
{ 
    selector: 'child-app', 
    template: ` 
    {{inputVariable}} 
    <input type="button" (click)="onButtonOneClick()" value="changeFoo"> 
    <ul> 
     <li *ngFor="#el of inputArray"> {{el}} </li> 
    </ul>   
    <input type="button" (click)="onButtonTwoClick()" value="ChangeLi">  
    ` 
}) 
export class ChildAppComponent { 
    @Input() inputVariable: string; 
    @Input() inputArray: string[]; 
    onButtonOneClick() { 
    this.inputVariable = 'new string'; 
    } 
    onButtonTwoClick() { 
    this.inputArray[0] = 'New element String'; 
    } 
} 

Родитель компонент имеет то же свойство и инициализирует дочерние компоненты, соответствующие свойства внутри шаблона ([inputArray]="inputArray" inputVariable="inputVariable") щелчки

import {Component} from 'angular2/core'; 
import {ChildAppComponent} from './childApp.component'; 

@Component({ 
selector: 'my-app', 
template: 
` 
{{inputVariable}} 
    <input type="button" (click)="onButtonOneClick()" value="changeFoo"> 
    <ul> 
     <li *ngFor="#el of inputArray"> {{el}} </li> 
    </ul>   
    <input type="button" (click)="onButtonTwoClick()" value="ChangeLi"> 
    <hr>  
    <child-app [inputArray]="inputArray" inputVariable="inputVariable"> </child-app> 
    `, 
    directives: [ChildAppComponent] 
    }) 
export class AppComponent { 
    inputVariable: string = 'foo'; 
    inputArray: string[] = ['one', 'two']; 

    onButtonOneClick() { 
     this.inputVariable = 'new string'; 
    } 
    onButtonTwoClick() { 
     this.inputArray[0] = 'New element String'; 
    } 
} 

Кнопки внутри родительских и дочерних компонентов изменяют значения соответствующего имущества (buttonOne ->inputVariable & buttonTwo - >inputArray)

При нажатии на вторую кнопку (которая изменяетсязначение) изменениесобственности происходит как в родителе и ребенок компонента

Когда щелчок на первую кнопку (которая изменяет string значения свойства) изменение только происходит внутри родителя или ребенка (соответствующего, к которому я нажал кнопку компоненты)

  • Почему поведение различается в зависимости от типа недвижимости?
  • Как установить привязку между двумя дочерними элементами и родительским компонентом string?

ответ

1

Для связывания от ребенка к родителю вам нужно использовать @Output()

двухстороннего связывание

import {Component, Inject, Input} from 'angular2/core'; 
@Component({ 
    selector: 'child-app', 
    template: ` 
    {{inputVariable}} 
    <input type="button" (click)="onButtonOneClick()" value="changeFoo"> 
    <ul> 
     <li *ngFor="#el of inputArray"> {{el}} </li> 
    </ul>   
    <input type="button" (click)="onButtonTwoClick()" value="ChangeLi">  
    ` 
}) 
export class ChildAppComponent { 
    @Input() inputVariable: string; 
    // v added 
    @Output() inputVariableChange:EventEmitter<string> = new EventEmitter<string>(); 
    @Input() inputArray: string[]; 
    // v added 
    @Output() inputArrayChange:EventEmitter<string[]> = new EventEmitter<string[]>(); 

    onButtonOneClick() { 
    this.inputVariable = 'new string'; 
    this.inputVariableChange.emit(this.inputVariable); 
    } 
    onButtonTwoClick() { 
    this.inputArray[0] = 'New element String'; 
    this.inputArrayChange.emit(this.inputArray); 
    } 
} 

в родителе использовать его как

{{inputVariable}} 
    <input type="button" (click)="onButtonOneClick()" value="changeFoo"> 
    <ul> 
     <li *ngFor="#el of inputArray"> {{el}} </li> 
    </ul>   
    <input type="button" (click)="onButtonTwoClick()" value="ChangeLi"> 
    <hr>  
    <!-- v added () 
    <child-app [(inputArray)]="inputArray" inputVariable="inputVariable"> </child-app> 

Именование актуально , Синтаксис связывания ярлыков [(xxx)]="yyy" работает только в том случае, если вход и выход обозначены @Input() xxx и @Output() xxxChange. в противном случае следует использовать длинную форму.

[xxx]="zzz" (xxxChange)="zzz = $event" 

обнаружения изменения

Угловая не проверяет изменения внутри объектов или массивов, это только проверяет, является ли объект или массив является другой объект или массив, чем раньше.

Если только свойство объекта было изменено или только был добавлен элемент/удалены/заменено, Угловой не заметят - например, в *ngFor как

<ul> 
    <li *ngFor="#el of inputArray"> {{el}} </li> 
</ul>   

, если привязать к свойству вместо только из пункта элемента, то *ngFor обнаруживает изменение

<ul> 
    <li *ngFor="#el of inputArray"> {{el.someProp}} </li> 
</ul>   

обойти это, например, чтобы создать новый массив

this.inputArray.slice(); 

или использовать новую функцию (beta.2) trackBy.
См. Также http://www.bennadel.com/blog/3020-understanding-object-identity-with-ngfor-loops-in-angular-2-beta-3.htm

создает копию (новый и другой массив), и это признается угловым как изменение.

+0

У меня есть сомнения, вы сказали, Контекстное связывание синтаксис [(ххх)] = «ууу» работает только, если вход и выход с именем ' @Input() xxx' и '@Output() xxxChange' ... Значит, если в родительском я использую -' 'и i child - '@Output() abc: EventEmitter = new EventEmitter();' .... и где-то 'this.abc.emit (this.inputVariable);'. Как насчет этого? – micronyks

+0

Я не совсем понимаю, что вы подразумеваете под этим комментарием. Соглашением является то, что для привязки к выводам вы используете '(outputName) =' и для входов, которые вы используете '[inputName]', но комбинированная форма '[(xxxName)]' работает только в том случае, если имена следуют шаблону '@Input() xxxName; @Output() xxxNameChange'. Имя ввода и вывода должно быть одинаковым, за исключением того, что на выходе нужен суффикс 'Change'. –

+0

Что я должен искать? '[(inputVariable)] =" inputVariable1 "' в 'boot.ts'? –

4

С помощью ввода вы можете внести изменения только по ссылке, если хотите, чтобы родительский компонент увидел обновление. Это относится к вашему массиву, но не для вашего свойства string (и, в более общем смысле, свойств с примитивными типами).

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

@Component({ 
    (...) 
}) 
export class ChildAppComponent { 
    @Input() inputVariable: string; 
    @Output() inputVariableChange: EventEmitter<string> = new EventEmitter(); 
    @Input() inputArray: string[]; 
    onButtonOneClick() { 
    this.inputVariable = 'new string'; 
    this.inputVariableChange.emit(this.inputVariable); 
    } 

    (...) 
} 

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

<child-app [inputArray]="inputArray" 
      [(inputVariable)]="inputVariable"> </child-app> 

ВИДЕТЬ [(...]) синтаксис. В этом случае inputVariable будет обновляться прозрачно, когда в дочернем компоненте будут созданы обновления для этого свойства.

Вы можете заметить, что Angular2 обнаруживает изменения только тогда, когда ссылка привязки изменяется не тогда, когда соответствующий контент (свойства объекта или элементы в массиве) обновляется.

Это поведение по умолчанию, но вы можете предоставить свои собственные на основе интерфейса DoCheck. Смотрите этот вопрос для этого случая использования:

+1

Это должен быть принятый ответ. –

Смежные вопросы