如何等待 api 中的数据加载,然后在 UI 中执行另一个操作?
How to wait for data from api to be loaded and then perform another action in the UI?
我有一个方法可以从 api 获取用户列表并填充列表组件。现在我想做什么
从 api 加载列表后,突出显示列表的第一个元素。
我已经尝试了以下方法并且它与 setTimeout 一起工作正常但是我如何在没有 setTimeout 函数的情况下实现它
这是我试过的代码,
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
我会删除 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;
}
在打字稿组件中:
selectedIndex = 0; //Default value.
onClick(index:number){
this.selectedIndex=index;
}
Tap 还接受一个对象映射来记录下一步、错误和完成
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();
}
});
}
你不应该那样操纵DOM,没有必要。我们使用 angular 绑定,通过使用这些绑定,我们还可以大大减少您当前拥有的代码。所以删除所有这些 DOM 操作。
首先,我们可以省略 parent 或 child 中的 lists
调用。现在你正在执行两次 get 请求,这实际上没有意义。我将 get-request 保留在 child 中。我们也可以在 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
,我们将根据点击的项目进行更改。就像延斯在他的回答中所做的那样。您希望第一个项目最初处于活动状态,我们在上面将 0
作为索引传递给 onClick
函数:
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>
如代码中的注释所述。不要使用 any
,它完全违背了 TypeScript 的目的,因此请使用接口或 类 输入您的数据。我更喜欢接口。
我有一个方法可以从 api 获取用户列表并填充列表组件。现在我想做什么 从 api 加载列表后,突出显示列表的第一个元素。 我已经尝试了以下方法并且它与 setTimeout 一起工作正常但是我如何在没有 setTimeout 函数的情况下实现它
这是我试过的代码,
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
我会删除 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;
}
在打字稿组件中:
selectedIndex = 0; //Default value.
onClick(index:number){
this.selectedIndex=index;
}
Tap 还接受一个对象映射来记录下一步、错误和完成
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();
}
});
}
你不应该那样操纵DOM,没有必要。我们使用 angular 绑定,通过使用这些绑定,我们还可以大大减少您当前拥有的代码。所以删除所有这些 DOM 操作。
首先,我们可以省略 parent 或 child 中的 lists
调用。现在你正在执行两次 get 请求,这实际上没有意义。我将 get-request 保留在 child 中。我们也可以在 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
,我们将根据点击的项目进行更改。就像延斯在他的回答中所做的那样。您希望第一个项目最初处于活动状态,我们在上面将 0
作为索引传递给 onClick
函数:
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>
如代码中的注释所述。不要使用 any
,它完全违背了 TypeScript 的目的,因此请使用接口或 类 输入您的数据。我更喜欢接口。