2016-03-15 4 views
1

У меня этот код ... Это пример учебного приложения, которое я пытаюсь построить, отражая ежедневные потребности разработчика. Фактически, когда пользователь набирает «огонь» на родительском компоненте, дочерний элемент выполняет событие, которое отправляет родительскому слову слово «booom». Это образец для демонстрации связи между дочерним компонентом, отправляющим сообщения в родительский компонент, с использованием @Input и OnChanges.Угловая 2 - Двусторонняя связь между компонентами

Теперь я пытаюсь сделать другое: родитель должен каким-то образом сообщить ребенку сообщение, подобное «Целевое закрытие» для ребенка, когда пользователь нажимает клавишу ввода (keyCode = 13). При этом у нас будет сценарий двухсторонней связи между компонентами.

Каков наилучший подход?

child.component

import {Component, Input, OnChanges, EventEmitter,Output, Injectable} from 'angular2/core'; 
@Injectable() 
@Component({ 
selector: 'child-component', 
template: `<p>I'm the child component</p> 
` 
}) 
export class ChildComponent implements OnChanges { 
@Input() txt: string; 
@Output() aim: EventEmitter<any> = new EventEmitter(); 
ngOnChanges(changes: {[propName: string]: SimpleChange}) { 
    var t = changes['txt'].currentValue; 
    if(t == 'fire') { 
     console.log('Fire !!!'); 
     this.aim.emit("booom !!!"); 
    } 
} 
} 

parent.component

import {Component} from 'angular2/core'; 
import {ChildComponent} from './child.component' 
@Component({ 
selector: 'parent-component', 
directives : [ChildComponent] 
template: `<p>I'm the parent component</p> 
<input type="textbox" [(ngModel)]="theModel" (keydown)="arrow($event)"> 
<p>feedback: {{feedback}}</p> 
<child-component txt="{{theModel}}" (aim)="feedback=$event"></child-component> 
` 
}) 
export class ParentComponent { 
theModel; 
feedback; 
arrow (evt){ 
    if(evt.keyCode ==13) { 
     //Need to cause an event on the child - a message like "Target Locked" 
    }; 
} 
} 
+0

Используйте '@Input()' для связи от родителя к дочернему элементу и '@Output()' для связи от дочернего элемента к родительскому объекту или использования службы. –

+0

«Теперь я пытаюсь по-другому:« Я не вижу здесь разницы. Просто используйте те же свойства ввода и вывода и отправьте разные сообщения или добавьте еще один набор свойств ввода и вывода. Также проверьте [кулинарная книга по взаимодействию компонентов] (https://angular.io/docs/ts/latest/cookbook/component-communication.html) –

+0

Родитель включает дочерний элемент ny с помощью импорта и селектор . Таким образом, родитель может захватить (цель) событие от ребенка. Мое сомнение заключается в том, чтобы сделать обратный путь: ребенок захватывает событие родителя. Помните, что у ребенка никогда не будет селектора родителя. Вот почему все по-другому. понял? –

ответ

2

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

Я думаю, что замешательство связано с тем, что вам не нужно событие. Для родительского сообщения → ребенка просто добавьте еще одно свойство ввода для ребенка. И привязать родительское свойство к нему:

<child-component [anotherInputProperty]="someParentProperty" ... 

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

if(evt.keyCode === 13) { 
    // Need to cause an event on the child - a message like "Target Locked". 
    // Just change the property value: 
    this.someParentProperty = "some new value"; 
    // Angular will take care of propagating the new value to the child 
}; 

Если вы хотите, чтобы ребенок выполнял некоторую логику при изменении значения входного свойства, реализуйте в дочернем объекте ngOnChanges().

Если проблема в том, что вы не хотите, чтобы изменить сообщение каждый раз, то вы можете либо

  • использование a shared service with an Observable и иметь ребенка subscribe() к наблюдаемым или
  • префиксом или суффиксом сообщение со случайным значением и отделить его от сообщения с помощью | или какого-либо другого персонажа, с которым вы можете разделить, так что в ребенке вы можете легко извлечь сообщение.

Вы также можете использовать тему, а не наблюдаемую в общей службе: см. Parent and children communicate via a service.

+0

ty, Mark !! Я проверю ваш ответ «завтра», и я не буду забывать отмечать вас как ответ, если это применимо. ты! –

+0

Ваше решение - это именно то, что я делаю на самом деле. Честно говоря, это не очень элегантно, но похоже, что это единственный приемлемый вариант :(Например, в моем реальном проекте у меня есть inputBox в моем родителе. Мне нужно вызвать реакцию (событие) в моем дочернем событии каждый раз, когда пользователь нажимает стрелка. Это может быть вверх и вниз. Итак, я использую ваше решение таким образом: if (event.keyCode == 40) {this.myChildProperty = 'down,' + Math.random();} - Если я дважды нажимаю кнопку вниз, случайный будет гарантировать, что событие будет выполнено. Но, честно говоря, мне действительно не нравится это решение. Но поскольку это единственный приемлемый, ok –

+0

@ MarcoS.Junior, так как вы продолжаете упоминать слово «event», похоже, что подход с общим сервисом (с Observable или Subject) был бы более подходящим для вашего использования, а не для свойства ввода. –

2

Вы могли бы обеспечить EventEmitter в качестве ввода дочернего компонента:

@Component({ 
    selector: 'child-component' 
    (...) 
}) 
export class ChildComponent { 
    @Input() 
    parentEventEmitter:EventEmitter; 

    ngOnInit() { 
    this.parentEventEmitter.subscribe((event) => { 

    }); 
    } 
} 

Ребенок мог бы подписаться на него будет извещен об этом ...

EventEmitter Это будет обеспечиваться таким образом, в качестве родительского компонента:

<child-component 
    [parentEventEmitter]="theEventEmitterFromTheParent"> 
</child-component> 
+0

Невозможно реализовать: ngOnInit() { this.parentEventEmitter.subscribe ((event) => { }); ---> this.parentEventEmitter.subscribe не является функцией в [стрелка в ParentComponent - я разместил это на plunker на https://plnkr.co/edit/nqlCl6r5Ib64MCYJA5v9 –

1

Вы должны реализовать эмиттер событий и подписаться на него в родительском компоненте. Ваше имя эмиттера должно соответствовать имени привязанного значения + «Изменить». Пример: если ваше значение «sum», ваше событие должно быть «sumChange» таким образом, вы можете сделать 2-стороннюю привязку от родительского liike [(sum)] = "value". Вот бухнуться пример:

https://plnkr.co/edit/efOGIJ0POh1XQeRZctSx?p=preview

+0

Звучит очень интересно, Моги! Я изучу это в понедельник, но мне понравилось! –

+0

Вы устанавливаете значение для родителя, в основном. Задача состоит в том, чтобы заставить родителя вызывать событие для ребенка. В моем примере, я поднимаю событие от ребенка к родительскому. –

+0

Ну, если вы заметили, что я изменяю значение от родителя и оно отражает в дочернем элементе, и когда я меняю его с дочернего, оно отражается в родительском. Это очень двусторонняя связь. Вы хотите сделать что-то другое? –

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