Angular 等待来自组件的服务订阅?
Angular wait service subscription from component?
我在第一次加载时填写用户自动完成时遇到问题。
这是我的 UsersService
:
public users: User[] = [];
constructor(private http: HttpClient) {
this.http.get<User[]>(environment.apiUrl + URLS.USERS).subscribe({
next: (res) => {
this.Users = res;
},
error: (err) => {
console.log(err);
},
});
}
filterUsers(val: string) {
return this.users.filter(
(user) =>
user.name.toLowerCase().includes(val.toLowerCase())
);
}
我在服务构造函数上得到 Users[]
,因为 this.users
将被多个组件使用。
另一方面,我有一个组件如下:
constructor(
private fb: FormBuilder,
public userService: UsersService) {
this.form = this.fb.group({
user: this.user = this.fb.control('')
});
this.filteredUsers = this.user.valueChanges.pipe(
startWith(''),
map((value: string) => this.userService.filterUsers(value))
);
}
和视图:
<mat-form-field class="example-full-width" appearance="outline">
<mat-label>User</mat-label>
<input type="text" matInput formControlName="user" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" [panelWidth]="'auto'">
<mat-option *ngFor="let sp of filteredUsers | async" [value]="sp.name">
{{sp.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
问题:第一次加载时,filterUsers
在http GET请求完成之前执行,所以this.users
为null,没有任何返回。聚焦时自动完成为空。
如果我输入任何内容,那么 this.users
已经有值并且列表会正确显示。
如何在第一次加载时设置自动完成的值?
与其将 filterUsers 放入构造函数中,不如将其放入 ngOnInit 中。
ngOnInit 在构造函数之后调用。
终于用 observables 解决了:
服务:
public users: User[] = [];
private subj = new BehaviorSubject('');
userObs = this.subj.asObservable();
constructor(private http: HttpClient) {
this.http.get<User[]>(environment.apiUrl + URLS.USERS).subscribe({
next: (res) => {
this.Users = res;
this.subj.next('ok');
},
error: (err) => {
console.log(err);
},
});
}
组件:
ngOnInit(): void {
this.userService.userObs.subscribe(x => { if (x == "ok") this.user.updateValueAndValidity(); });
}
我在第一次加载时填写用户自动完成时遇到问题。
这是我的 UsersService
:
public users: User[] = [];
constructor(private http: HttpClient) {
this.http.get<User[]>(environment.apiUrl + URLS.USERS).subscribe({
next: (res) => {
this.Users = res;
},
error: (err) => {
console.log(err);
},
});
}
filterUsers(val: string) {
return this.users.filter(
(user) =>
user.name.toLowerCase().includes(val.toLowerCase())
);
}
我在服务构造函数上得到 Users[]
,因为 this.users
将被多个组件使用。
另一方面,我有一个组件如下:
constructor(
private fb: FormBuilder,
public userService: UsersService) {
this.form = this.fb.group({
user: this.user = this.fb.control('')
});
this.filteredUsers = this.user.valueChanges.pipe(
startWith(''),
map((value: string) => this.userService.filterUsers(value))
);
}
和视图:
<mat-form-field class="example-full-width" appearance="outline">
<mat-label>User</mat-label>
<input type="text" matInput formControlName="user" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" [panelWidth]="'auto'">
<mat-option *ngFor="let sp of filteredUsers | async" [value]="sp.name">
{{sp.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
问题:第一次加载时,filterUsers
在http GET请求完成之前执行,所以this.users
为null,没有任何返回。聚焦时自动完成为空。
如果我输入任何内容,那么 this.users
已经有值并且列表会正确显示。
如何在第一次加载时设置自动完成的值?
与其将 filterUsers 放入构造函数中,不如将其放入 ngOnInit 中。 ngOnInit 在构造函数之后调用。
终于用 observables 解决了:
服务:
public users: User[] = [];
private subj = new BehaviorSubject('');
userObs = this.subj.asObservable();
constructor(private http: HttpClient) {
this.http.get<User[]>(environment.apiUrl + URLS.USERS).subscribe({
next: (res) => {
this.Users = res;
this.subj.next('ok');
},
error: (err) => {
console.log(err);
},
});
}
组件:
ngOnInit(): void {
this.userService.userObs.subscribe(x => { if (x == "ok") this.user.updateValueAndValidity(); });
}