首页 > 解决方案 > mat-select 值未在路线更改时保存,Angular 8

问题描述

当用户离开然后返回使用 routerState.snapshot 的按钮(确实收集正确的路线)时,为“选择您的出版物”下拉列表选择的值不会保存在下拉列表中。下拉菜单返回占位符(“全部”)。“选择您的模型”下拉菜单非常适合保存选择。由于发布下拉列表等待模型选择,可能 Angular 以错误的顺序加载(?)。当我控制台记录 this.selectedManual 它总是返回未定义。this.selectedModel 的控制台日志返回正确的值。

组件.ts...

...

manuals: Toc[];
  models: string[];
  selectedModel: string;
  selectedManual: any;

  routerSubscription: Subscription;

  constructor(
    private productService: UserProductService,
    private tocService: TocService,
    private routeService: RouteService,
    private route: ActivatedRoute,
    private router: Router,
    public offlineService: OfflineService
  ) { }

  ngOnInit() {
    this.getModels();
    this.trackRoute();

    this.routerSubscription = this.router.events.subscribe(
      (event: Event) => {
        if (event instanceof NavigationEnd) {
          this.trackRoute();
        }
      }
    );
    console.log("model  " + this.selectedModel);
    console.log("manual  " + this.selectedManual);


  }

  ngOnDestroy(): void {
    if (this.routerSubscription) {
      this.routerSubscription.unsubscribe();
    }
  }

  async trackRoute(): Promise<void> {
    if (this.route.snapshot.children.length > 0) {
      const routeModelName = this.routeService.getParameter('model');
      const routeManualName = this.routeService.getParameter('manual');
      this.selectedModel = routeModelName;
      await this.loadManuals();
      this.selectedManual = this.getManualFromManualList(routeManualName);
    }
  }

  getModels() {
    this.productService.getUserModels()
    .subscribe(data => {
      this.models = data;
    })
  }

  changeModel(event) {
    this.selectedModel = event.value;
    this.loadManuals();
    this.router.navigate(['toc', this.selectedModel]);
  }

  loadManuals() {
    this.manuals = undefined;
    this.selectedManual = undefined;
    if (this.selectedModel) {
      this.tocService.getModelToc(this.selectedModel)
      .subscribe((data) => {
        this.manuals = data.toc;
      });
    }
  }

  changeManual(event) {
    this.selectedManual = this.getManualFromManualList(event.value);
    if (this.selectedManual) {
      this.router.navigate(['toc', this.selectedModel, this.selectedManual.toc]);
      console.log("manual is " + event.value);


    }
  }

  private getManualFromManualList(toc: string): any {
    if (this.selectedModel && this.manuals) {
      for (let i = 0; i < this.manuals.length; i++) {
        if (this.manuals[i].toc === toc) {
          return this.manuals[i];
        }        
      }
    }
    return null;
  }


  showFindPublicationDialog() {
    this.findPublicationClick.emit('show');
  }
}

.html...


<section class="side-nav-selects">
  <div class="model-selection">
    <h5 class="model-selection-title">Select your Model</h5>
    <h5 class="model-selection-title title-mini">Model</h5>
    <mat-form-field appearance="outline" floatLabel="never">
      <mat-select value="{{selectedModel}}" placeholder="Select a Model" (selectionChange)="changeModel($event)" [disabled]="!models || models.length == 0">
        <mat-select-trigger class="model-selection-trigger" *ngIf="selectedModel">
          {{selectedModel}}<mat-icon class="offline-ready-selected" *ngIf="offlineService.isElectron && selectedModel == '407'">done</mat-icon>
        </mat-select-trigger>
        <mat-option class="model-selection-option" *ngFor="let model of models" [value]="model">
          {{model}}<mat-icon class="offline-ready" *ngIf="offlineService.isElectron && model == '407'">done</mat-icon>
        </mat-option>
      </mat-select>
    </mat-form-field>
  </div>
  <div class="publication-selection">
    <h5 class="publication-selection-title">Select your Publication</h5>
    <h5 class="publication-selection-title title-mini">Publication</h5>
    <mat-form-field appearance="outline">
      <mat-select value="{{selectedManual ? selectedManual.toc: null}}" placeholder="All" [disabled]="selectedModel == null" (selectionChange)="changeManual($event)">
        <mat-option *ngFor="let manual of manuals" [value]="manual.toc">{{manual.manual}}</mat-option>
      </mat-select>
    </mat-form-field>
  </div>
</section>



标签: angular

解决方案


我得到了不正确的行为,因为 trackRoute() 是一个等待 this.loadManuels() 的异步函数,但 loadManuels() 不是一个承诺,它是一个 Observable。这导致了一些空值。在进行这些更改(如下)时,问题得到了解决。

 trackRoute() {
    if (this.route.snapshot.children.length > 0) {
      const routeModelName = this.routeService.getParameter('model');
      const routeManualName = this.routeService.getParameter('manual');
      this.selectedModel = routeModelName;
      this.loadManuals(routeManualName);
    }
  }


  loadManuals(manualName?: string) {
    this.manuals = undefined;
    this.selectedManual = undefined;
    if (this.selectedModel) {
      this.tocService.getModelToc(this.selectedModel)
      .subscribe((data) => {
        this.manuals = data.toc;
        if(manualName) {
          this.selectedManual = this.getManualFromManualList(manualName);
        }
      });
    }
  }



推荐阅读