асинхронный канал работает только при вызове setTimeout - PullRequest
0 голосов
/ 21 октября 2019

https://stackblitz.com/edit/angular-4pvirk

Это какая-то ошибка?

  runOnInitandOnChanges() {
    setTimeout(() => {this.sc1.updateValueAndValidity(); }, 0);
  }

, почему я должен позвонить setTimeout?

  runOnInitandOnChanges() {
    this.sc1.updateValueAndValidity();
  }

. не работает, также, если я звоню detectChanges() в OnInit и / или AfterViewInit.

Иногда я сталкиваюсь со случаями, когда только setTimeout, кажется, решает проблему, и это взломанный AF, и я не понимаю этого.

Есть идеи?

html

<ng-container *ngIf="domain$ | async as domain$T">
    <ng-container *ngIf="_domainData?.length">
        <mat-form-field style="display: block;">
            <mat-label>Liste durchsuchen</mat-label>
            <input matInput type="text" class="form-control" [formControl]="sc1">
        </mat-form-field>

        <mat-nav-list class="domainListMatList maya-border-dark" *ngIf="domain$T.length">
            <ng-container *ngFor="let domain of domain$T">
                <a mat-list-item href="javascript:void(0)" (click)="showDomain(domain)">
                    {{domain}}
                </a>
            </ng-container>                                                        
        </mat-nav-list>
    </ng-container>
</ng-container>

ts

export class DynFilterListComponent implements OnInit, AfterViewInit { //, OnChanges {

  @Input() _domainData: any[];

  _domain = new Subject<any[]>();
  domain$: Observable<any[]>;
  sc1 = new FormControl();

  @Output() itemClicked = new EventEmitter<any>();

  constructor(private readonly cd: ChangeDetectorRef) {
    this.domain$ = this._domain.asObservable();
  }

  runOnInitandOnChanges() {
    //setTimeout(() => {this.sc1.updateValueAndValidity(); }, 0);
    // does not work if only this.sc1.updateValueAndValidity();
    // despite calling this.cd.detectChanges(); in ngOnInit and ngAfterViewInit
    this.sc1.updateValueAndValidity();
  }

  ngOnInit() {
  /**/
    this.sc1.valueChanges
    .subscribe( v => {
      this._domain.next( 
        v ? 
          this._domainData.filter( (dn: string) => dn.includes(v)) :
          this._domainData
      )
    });

    this.runOnInitandOnChanges();

    this.cd.markForCheck();
    this.cd.detectChanges();
  }

  ngOnChanges(changes: SimpleChanges) {
    if ('_domainData' in changes) {
      // this.runOnInitandOnChanges();
    }
  }

  ngAfterViewInit() {
    this.cd.markForCheck();
    this.cd.detectChanges();
  }
/**/
  showDomain(value: any) {
    this.itemClicked.next(value);
  }
...