我正在进行一个项目,需要加载和选择客户端(不是用户,而是更像客户)。
不幸的是,我似乎无法订阅我正在加载的组件中的可观测数据。我已经尝试了所有可能的解决方案,我可以在网上找到,但也许我的经验,角是阻止我找到正确的一个。
现在起作用的是:
因此,我唯一的问题是,组件没有注意到client.service中可观察到的变化。
这是我的client.service.ts:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { ApiService } from '../api.service';
import { Client } from './client';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';
@Injectable()
export class ClientService {
clients$: Observable<Client[]>;
client: Client;
selectedClient$: Observable<Client[]>;
constructor(private api: ApiService) {
this.clients$ = this.getAll();
}
public getAll(): Observable<Client[]> {
return this.api.get<Client[]>('clients');
}
public setSelectedClient(clientId: number) {
this.clients$ = this.getAll();
if (clientId == null) {
// Do nothing
} else {
this.selectedClient$ = this.clients$.map(arr =>
{ return arr.find(client => client.id === clientId) });
}
}
public getSelectedClient() : Observable<Client> {
return this.selectedClient$;
}
}我的组件,带有注释位,显示了修复我的问题的一些尝试:
import { Component, OnInit } from '@angular/core';
import { Observable } from "rxjs/Observable";
import { ClientService } from "../client/client.service";
import { Client } from "../client/client";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';
@Component({
selector: 'app-left-menu',
templateUrl: './left-menu.component.html',
styleUrls: ['./left-menu.component.css']
})
export class LeftMenuComponent implements OnInit {
selectedClient$ : Observable<Client>;
client: Client = new Client();
clients$ : Observable<Client[]>;
constructor(private clientService: ClientService) {
}
ngOnInit() {
// this.clientService.getSelectedClient().subscribe(selectedClient$ => {
// this.selectedClient$ = Observable.of(selectedClient$);
// });
// //
// this.clientService.getAll().subscribe(clients$ => {
// this.clients$ = Observable.of(clients$);
// });
this.selectedClient$ = this.clientService.getSelectedClient();
this.clients$ = this.clientService.getAll();
}
public setSelectedClient(clientId: number) {
this.clientService.setSelectedClient(clientId);
}
}html中用于显示和选择客户端的部分:
<select #selectClient [ngModel]="selectedClient$ | async"
(ngModelChange)="setSelectedClient(selectClient.value)">
<option *ngFor="let client of clients$ | async" [value]="client.id">
{{ client.firstName }}
{{ client.preposition }}
{{ client.lastName }}
</option>
</select>
<!-- Displaying selected client -->
<h2 *ngIf="selectedClient$">{{(selectedClient$ | async)?.firstName}}
</h2>如果有人能帮我解决这个问题,那将是非常感谢的,谢谢!
发布于 2017-12-10 16:19:39
使用[ngValue]而不是[value] (允许将客户端对象本身绑定到[ngModel]指令),我还使用Subject轻松地通知新选定客户端的其他订阅者:
client.service.ts:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { Client } from './client';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';
@Injectable()
export class ClientService {
clients$: Observable<Client[]>;
client: Client;
selectedClient$: Subject<Client> = new Subject<Client>();
//...
public setSelectedClient(client: Client) {
if (client)
this.selectedClient$.next(client);
}
//...
}component.ts:
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { ClientService } from './client.service';
import { Client } from './client'
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
selectedClient : Client;
client: Client = new Client();
clients$ : Observable<Client[]>;
constructor(private clientService: ClientService) {
}
ngOnInit() {
//...
this.clients$ = this.clientService.getAll();
this.clientService.selectedClient$.subscribe(console.log)
}
setSelectedClient(client : Client){
this.selectedClient = client;
this.clientService.setSelectedClient(client)
}
}模板:
<select #selectClient [ngModel]="selectedClient"
(ngModelChange)="setSelectedClient($event)">
<option *ngFor="let client of clients$ | async" [ngValue]="client">
{{ client.firstName }}
{{ client.preposition }}
{{ client.lastName }}
</option>
</select>发布于 2017-12-10 16:06:34
您的问题来自您将clients$和selectedClient$可观察属性分配给LeftMenuComponent的方式。
setSelectedClient()方法在ClientService上将更改服务的属性。但是,您的LeftMenuComponent的ngOnInit()只分配属性一次,而来自setSelectedClient()的更改不会反映在LeftMenuComponent上。
要使此工作正常,不需要将属性重新分配给组件。您可以简单地将服务的属性直接绑定到模板中,如下所示:
<select #selectClient [ngModel]="clientService.selectedClient$ | async"
(ngModelChange)="setSelectedClient(selectClient.value)">
<option *ngFor="let client of clientService.clients$ | async" [value]="client.id">
{{ client.firstName }}
{{ client.preposition }}
{{ client.lastName }}
</option>
</select>另一个可能更简洁的选择是在组件上使用getter属性而不是分配,如下所示:
export class LeftMenuComponent implements OnInit {
client: Client = new Client();
get selectedClient$(): Observable<Client> {
return this.clientService.selectedClient$;
}
get clients$(): Observable<Client> {
return this.clientService.client$;
}
constructor(private clientService: ClientService) {
}
ngOnInit() {
// init things, but no assignment needed now
}https://stackoverflow.com/questions/47740365
复制相似问题