Angular: set selected value for <select>

半腔热情 提交于 2019-12-14 03:47:47

问题


I have data set for my <select> loaded asynchronously. I use hot observable, as the data can change in time. The problem is I am unable to set selected value and also Angular does not point to first element by itself (there is no value set until user does it). I'm trying to subscribe to my own observable and... it doesn't work, I wonder why? How can I solve this problem?

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();
    }
  }
}

回答1:


You subscribe to your observable twice. Async pipe does it internally after your subscription.

When subscribe method is being executed it executes subscribe function

observer => this.observer = observer

and overrides this.observer property so it will have effect only for async pipe(last subscriber)

I would use share operator to solve it

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

Plunker Example

To see why this.observer is overrided just run this code

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

As i mentioned early async pipe subscribes to observable internally

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




回答2:


You should be using

[ngValue]="value" 

instead of [value]

Assigned a value as

public selectedValue: string = 'test';

HTML should be changed as

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

Updated Plunker




回答3:


You should bind it to ngValue:

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


来源:https://stackoverflow.com/questions/45122300/angular-set-selected-value-for-select

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!