簡體   English   中英

如何等待來自 api 的數據被加載,然后在 UI 中執行另一個操作?

[英]How to wait for data from api to be loaded and then perform another action in the UI?

我有一個從 api 獲取用戶列表並填充列表組件的方法。 現在我要做的是在從 api 加載列表后突出顯示列表的第一個元素。 我已經嘗試了以下方法,它與 setTimeout 一起工作得很好,但是如果沒有 setTimeout function 我怎么能做到這一點

這是我嘗試過的代碼,

public getUserList(){ 
    return this.http.get('https://jsonplaceholder.typicode.com/users').pipe(tap(x => {
      this.lists = x;
    }))
    .subscribe((data) => {
      setTimeout(() => { 
        this.clickFirstList();
      }, 1000);
    });
  }

clickFirstList() {
    Array.from(this.ulElement.nativeElement.children).forEach((element: HTMLElement, index: number) => {
      if (index === 0) {
        console.log(element);
        element.click();
      }
    });
}

這是 stackblitz 上的工作代碼。 https://stackblitz.com/edit/angular-brpz2j?file=src/app/search-list.component.ts

你不應該那樣操作 DOM,沒有必要。 我們使用 angular 綁定,通過使用這些綁定,我們還可以大大減少您當前擁有的代碼。 所以刪除所有這些 DOM 操作。

首先,我們可以省略來自父母或孩子的lists調用。 現在您正在執行兩次 get 請求,這實際上沒有任何意義。 我將獲取請求保留在孩子身上。 我們也可以在 OnInit 中進行請求,為什么我們需要在AfterViewInit中進行呢?

ngOnInit() {
  this.getUserList();
}

public getUserList() {
  return this.http
     // DONT USE 'ANY', type your data using interface or class
    .get<any[]>("https://jsonplaceholder.typicode.com/users")
    .subscribe(data => {
      this.lists = data;
      // you want to emit initially the first item to parent via output
      // do it here.
      this.onClickList(0, this.lists[0] || {})
    });
 }

我們還引入了一個新變量selectedIndex ,我們將根據單擊的項目進行更改。 就像 Jens 在他的回答中所做的那樣。 您希望第一個項目最初處於活動狀態,我們將0作為索引傳遞給onClick function:

public onClickList(i: number, item: any) {
  this.selectedIndex = i
  this.selectedList.emit(Object.assign({}, item));
}

我們將它添加到模板中,如下所示:

<ng-container *ngFor="let item of lists | filter: searchText; index as i">
  <li [class.active]="i === selectedIndex"
    (click)="onClickList(i, list)">
    {{ list.name }}
  </li>
</ng-container>

你的分叉 STACKBLITZ

如代碼中的注釋所述。 不要使用any ,它完全違背了Type Script 的目的,因此請使用接口或類鍵入您的數據。 我更喜歡接口。

Tap 還接受 object map 以記錄下一個、錯誤和完成

  public getUserList(){ 
    return this.http.get('https://jsonplaceholder.typicode.com/users')
    .pipe(
       tap( {
         next: x => {
           console.log('on next', x);
         },
         error: error => {
           console.log('on error', error.message);
         },
         complete: () => {
           console.log('on complete')
           this.clickFirstList()
         }
       }))
       .subscribe((x) => {
        console.log(x)
       });
  }

您可以使用以下代碼

public getUserList(){ 
    return this.http.get('https://jsonplaceholder.typicode.com/users').pipe(tap(x => {
      this.lists = x;
    }))
    .subscribe((data) => {
    },
    (err) => {
        // code to execute if request fails
    },
    () => {
    this.clickFirstList();
    }
  });
}

我會刪除 clickFirstList。 並使用 css 和 angular。

我現在不知道你循環使用什么 html 元素,但可以說它是一個列表,例如:html

<ul>
  <li *ngFor="let user of list:let index = index" [class.selected]="index===selectedIndex" (click)="onClick(index)> 
    {{user.Name}}
  </li>
</ul>

和 css

.selected{
   background-color: yellow;
}

在 typescript 組件中:

selectedIndex = 0; //Default value. 
onClick(index:number){
   this.selectedIndex=index;
}  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM