2017-07-15 3 views
2

Ich habe Daten für meine <select> asynchron geladen. Ich benutze heiß beobachtbar, da sich die Daten im Laufe der Zeit ändern können. Das Problem ist, dass ich den ausgewählten Wert nicht setzen kann und auch Angular nicht auf das erste Element selbst zeigt (es gibt keinen Wert, bis der Benutzer es tut). Ich versuche mein eigenes Observable zu abonnieren und ... es funktioniert nicht, ich frage mich warum? Wie kann ich dieses Problem lösen?Angular: Setzen Sie den ausgewählten Wert für <select>

PLNKR: https://plnkr.co/edit/uDmTSHq4naYGUjjhEe5Q

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Hello {{name}}</h2> 
    </div> 
    <select [(ngModel)]="selectedValue"> 
     <option *ngFor="let value of (values$ | async)" 
       [value]="value">{{ value }} 
     </option> 
    </select> 
    `, 
}) 
export class App implements OnInit, OnDestroy { 
    public name: string; 
    public selectedValue: string = ''; 
    public values$: Observable<Array<string>> = new Observable(observer => this.observer = observer); 
    protected observer: Subscriber<Array<string>>; 
    protected subscription: Subscription; 

    constructor() { 
    this.name = `Angular! v${VERSION.full}` 
    } 

    ngOnInit() { 
    this.subscription = this.values$.subscribe((values) => { 
     console.log('never fired...'); 
     this.selectedValue = values[0]; 
    }); 

    setTimeout(() => { 
     this.observer.next(['some', 'test', 'data']); 
    }); 
    } 

    ngOnDestroy() { 
    if (this.subscription) { 
     this.subscription.unsubscribe(); 
    } 
    } 
} 

Antwort

5

Sie zweimal auf Ihre beobachtbare abonnieren. Async-Pipe macht es intern nach Ihrem Abonnement.

Wenn subscribe Verfahren ausgeführt wird es subscribe Funktion

observer => this.observer = observer 

und überschreibt this.observer Eigenschaft ausführt, so dass es nur wirksam für async Rohr (letzte Teilnehmer)

haben I share Bediener es benutzen würde zu lösen

new Observable(observer => this.observer = observer).share(); 

Plunker Example

Um zu sehen, warum this.observer nur

let myObserver; 

const observable$ = new Rx.Observable(function subscribe(observer) { 
    console.log('subscribe function has been called'); 
    myObserver = observer; 
}); 

observable$.subscribe(function next1() { console.log('next1'); }); 
observable$.subscribe(function next2() { console.log('next2'); }); 
observable$.subscribe(function next3() { console.log('next3'); }); 

myObserver.next(); 

jsbin.com

Wie ich früh async Rohr abonniert beobachtbaren erwähnt intern

https://github.com/angular/angular/blob/4.3.x/packages/common/src/pipes/async_pipe.ts#L23

+0

Dies ist die genaue Antwort +1, danke für das Teilen von Tipps Angular Star * –

+0

Perfekt! Danke, könntest du auch mehr erklären, wie die "asynchrone" Pipe den Beobachter überschreibt? Ich habe gedacht, dass es bis jetzt sicher ist, mehrere Abonnements zu haben. –

1

Sie mit

[ngValue]="value" 

statt [Wert] sollte

Wert als

Assigned
public selectedValue: string = 'test'; 

HTML sollte geändert, wie

<select [(ngModel)]="selectedValue"> 
    <option *ngFor="let value of values$ | async" 
      [ngValue]="value">{{ value }} 
    </option> 
</select> 

Updated Plunker

+3

Bitte beachten Sie, dass ich diesen Code overrided ausgeführt kenne den Anfangswert nicht - die Daten sind dynamisch. –

+0

@DanielKucal von wo erhalten Sie den dynamischen Wert? – Aravind

+0

Nehmen wir an, es kommt vom Server –

1

Sie es ngValue binden sollte:

<div> 
     <h2>Hello {{name}}</h2> 
    </div> 
    <select [(ngModel)]="selectedValue"> 
     <option *ngFor="let value of (values$ | async)" 
       [ngValue]="selectedValue">{{ value }} 
     </option> 
    </select> 
+0

Ich habe auch das versucht, hat nicht funktioniert –

+0

Ich habe es gerade in Plunker getestet und es hat funktioniert. [Link] (https: // plnkr.co/edit/UUVUNcaG996q38pN8gSo? p = Vorschau) –

+0

Es sieht so aus, als ob Sie arbeiten, weil Sie echte Werte durch 'selectedValue' ersetzt haben und jetzt der Wert nicht richtig eingestellt ist ... [link] (https://plnr.rc/edit/CE32tNcdfqnSiTG5SEzI) –

Verwandte Themen