2016-01-05 14 views
8

Próbuję zrobić coś na temat kąta2 i nie jestem w stanie znaleźć czegoś na temat tego zachowania.Dwukierunkowe powiązanie danych we właściwości wejściowej komponentu

Mam aplikacji, która implementuje niestandardowy składnik podobny do tego:

import {Component,Input} from 'angular2/core' 
    @Component({ 
     selector:'my-comp', 
     template:`<input type="text" style="text-align:center; [(ngModel)]="inputText"> <p>{{inputText}}</p>` 
    }) 

    export class MyComp{ 
     @Input() inputText : string; 
    } 

i próbuję zrobić dwukierunkową wiązania z danymi w moim zmiennej inputText z mojego komponentu tak:

<my-comp [(inputText)]="testString"></my-comp> 

Gdzie testString jest zmienną zdefiniowaną w MyApp.ts, która zawiera ciąg znaków. Chcę, aby moja zmienna testString została zmodyfikowana, gdy mój inputText został zmodyfikowany przez użytkownika.

Oto Plunker z prostym przykładowy kod: https://plnkr.co/edit/zQiCQ3hxSSjCmhWJMJph?p=preview

Czy istnieje sposób, aby to po prostu działa? Czy muszę implementować klasę Angular2 w swoich niestandardowych komponentach i funkcjach przeciążeniowych, aby działał on tak jak ngModel? Czy muszę koniecznie trzeba utworzyć inputTextChanged zmienną EventEmitter typu, które emitują swoje dane, kiedy to zmienił i zrobić coś takiego:

<my-comp [inputText]="testString" (inputTextChanged)="testString = $event;"></my-comp> 

Z góry dziękuję.

+2

Tak, musisz utworzyć emiter zdarzeń "inputTextChanged" i wywołać zdarzenie wewnątrz komponentu. Następnie [(inputText)] powinien działać zgodnie z oczekiwaniami. – pixelbits

+0

Uwaga: nie ma czegoś takiego jak dwukierunkowe wiązanie danych w Angular2, ale możesz mieć podobne zachowanie. http://victorsavkin.com/post/110170125256/change-detection-in-angular-2 – jornare

+0

Cóż, zgodnie z Arkuszem Cheular Angular2 z oficjalnej strony internetowej: " \t Konfiguruje dwukierunkowe powiązanie danych. Odpowiednik: ". Więc myślę, że możemy powiedzieć, że jest dwukierunkowe wiązanie danych w Angular2. –

Odpowiedz

14

Jest to wyjaśnione w dokumencie składni szablonu, w sekcji Two-Way Binding with NgModel:

<input [(ngModel)]="currentHero.firstName">

Wewnętrznie kątowa odwzorowuje metę ngModel, do mienia wejściowego ngModel i mienia ngModelChange wyjściowego. Jest to konkretny przykład bardziej ogólnego wzorca, który pasuje do [(x)] do właściwości wejściowej x dla powiązania właściwości i do właściwości wyjściowej xChange dla powiązania zdarzeń.

Możemy napisać naszą własną, dwukierunkową dyrektywę/komponent, która podąża za tym wzorcem, jeśli kiedykolwiek będziemy mieli na to ochotę.

Należy również zauważyć, że [(x)] jest po prostu cukier syntaktyczny dla właściwości wiązania i zdarzenie wiążące:

[x]="someParentProperty" (xChange)="someParentProperty=$event" 

W twoim przypadku, chcesz

<my-comp [(inputText)]="testString"></my-comp> 

więc komponent musi mieć inputText właściwość wejściowa i właściwość wyjściowa inputTextChange (która jest EventEmitter).

export class MyComp { 
    @Input() inputText: string; 
    @Output() inputTextChange: EventEmitter<string> = new EventEmitter(); 
} 

powiadomić rodziców o zmianach, gdy komponent zmienia wartość inputText emitują zdarzenia:

inputTextChange.emit(newValue); 

W swoim scenariuszu składnik Mycomp wiąże właściwość wejście inputText pomocą [(x)] format do ngModel, więc użyłeś wiązania zdarzeń (ngModelChange), aby otrzymać powiadomienie o zmianach, iw takim przypadku moduł obsługi, który powiadomiłeś element macierzysty o zmianie.

W innych scenariuszach, w których ngModel nie jest używany, ważne jest, aby emit() zdarzenie miało miejsce, gdy wartość właściwości inputText zmieni się w składniku MyComp.

+0

Aktualizacja Angular4: W komponencie potomnym nie jest już konieczne określanie danych wyjściowych EventEmitter. Jest to obsługiwane automatycznie przez @input. Widok nadrzędny: dzieci komponent: eksport klasy Mycomp { @Input() inputText string; } – switch87

1

Twój Plunker zawiera już EventEmitter. Brakuje adnotacji @Output(). Aby zmienić wywołanie wartości inputTextChanged.emit(newValue) (zmieni to również wartość na inputText)

+0

Tak Przepraszam, jestem nowy w plunker i zapomniałem zablokować plunkera do stanu, który chciałem, abyś zobaczył i kontynuował mój test na tym, żebyś zobaczył moje modyfikacje. –

+0

Ho Właśnie przypomniałem sobie i nie wiem, czy to wiesz, ale przynajmniej z wersji beta Angular2 ".next()" jest przestarzałe i powinieneś użyć ".emit()". –

+0

Dzięki! nie widziałem tego. –

6

Będę łączyć @pixelbits i @ Günter Zöchbauer odpowiedzi i komentarze, aby uzyskać jasną odpowiedź na moje pytanie, czy ktoś w przyszłości szuka tego.

Aby powiązanie danych dwukierunkowych działało na zmiennych niestandardowych, należy utworzyć komponent w oparciu o następujące elementy. złożyć

MyComp.ts: plik

import {Component,Input,Output,EventEmitter} from 'angular2/core' 
@Component({ 
    selector:'my-comp', 
    templateUrl:`<input type="text" style="text-align:center;" 
    [ngModel]="inputText" (ngModelChange)="inputText=$event;inputTextChange.emit($event);">` 
}) 

export class MyComp{ 
    @Input() inputText : string; 
    @Output() inputTextChange = new EventEmitter(); 
} 

MyApp.ts:

import {Component} from 'angular2/core' 
import {MyComp} from './MyComp' 

@Component({ 
    selector:'my-app', 
    templateUrl:`<h1>Bidirectionnal Binding test </h1> 
    <my-comp [(inputText)]="testString"></my-comp><p> 
    <b>My Test String :</b> {{testString}}</p>`, 
    directives:[MyComp] 
}) 

export class MyApp{ 
    testString : string; 
    constructor(){ 
    this.testString = "This is a test string"; 
    } 
} 

tam danych dwukierunkowych wiązania zmiennej inputText działa poprawnie. Możesz skomentować odpowiedź na piękniejszy lub prostszy sposób zaimplementowania tego kodu.

Powiązane problemy