javascript - Angular: sett valgt verdi for <select>
Jeg har datasett for min <select> som lastes asynkront. Jeg bruker hot observable, da dataene kan endre seg over tid. Problemet er at jeg ikke klarer å sette valgt verdi, og Angular peker heller ikke på det første elementet selv (det er ingen verdi satt før brukeren gjør det). Jeg prøver å abonnere på min egen observable og... det fungerer ikke, jeg lurer på hvorfor? Hvordan kan jeg løse dette problemet?
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();
}
}
}
Svar #1
Du abonnerer på observablen din to ganger. Async-pipe gjør det internt etter abonnementet ditt.
Når subscribe-metoden blir utført, kjører den subscribe-funksjonen
observer => this.observer = observer
og overstyrer this.observer-egenskapen slik at den kun vil ha effekt for async pipe (siste abonnent)
Jeg ville brukt share-operatoren for å løse det
new Observable(observer => this.observer = observer).share();
Plunker-eksempel
For å se hvorfor this.observer er overstyrt, kjør bare denne koden
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
Som jeg nevnte tidligere, abonnerer async-pipen på observable internt
https://github.com/angular/angular/blob/4.3.x/packages/common/src/pipes/async_pipe.ts#L23
Svar #2
Du bør bruke
[ngValue]="value"
i stedet for [value]
Tildelt en verdi som
public selectedValue: string = 'test';
HTML bør endres som
<select [(ngModel)]="selectedValue">
<option *ngFor="let value of values$ | async"
[ngValue]="value">{{ value }}
</option>
</select>
Oppdatert Plunker
