首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角4:订阅可观测到的

角4:订阅可观测到的
EN

Stack Overflow用户
提问于 2017-12-10 15:33:36
回答 2查看 6.4K关注 0票数 2

我正在进行一个项目,需要加载和选择客户端(不是用户,而是更像客户)。

不幸的是,我似乎无法订阅我正在加载的组件中的可观测数据。我已经尝试了所有可能的解决方案,我可以在网上找到,但也许我的经验,角是阻止我找到正确的一个。

现在起作用的是:

  • 在选中框中加载客户端
  • 在选中框中将客户端id的值赋值给选项
  • 将客户端的id发送到client.service,并将选定的客户机保存为可观察的

因此,我唯一的问题是,组件没有注意到client.service中可观察到的变化。

这是我的client.service.ts:

代码语言:javascript
复制
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$;
    }

}

我的组件,带有注释位,显示了修复我的问题的一些尝试:

代码语言:javascript
复制
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中用于显示和选择客户端的部分:

代码语言:javascript
复制
 <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>

如果有人能帮我解决这个问题,那将是非常感谢的,谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-10 16:19:39

演示

使用[ngValue]而不是[value] (允许将客户端对象本身绑定到[ngModel]指令),我还使用Subject轻松地通知新选定客户端的其他订阅者:

client.service.ts:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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)
    }
}

模板:

代码语言:javascript
复制
<select #selectClient [ngModel]="selectedClient" 
(ngModelChange)="setSelectedClient($event)">
     <option *ngFor="let client of clients$ | async" [ngValue]="client">
         {{ client.firstName }}
         {{ client.preposition }}
         {{ client.lastName }}
     </option>
</select>
票数 1
EN

Stack Overflow用户

发布于 2017-12-10 16:06:34

您的问题来自您将clients$selectedClient$可观察属性分配给LeftMenuComponent的方式。

setSelectedClient()方法在ClientService上将更改服务的属性。但是,您的LeftMenuComponentngOnInit()只分配属性一次,而来自setSelectedClient()的更改不会反映在LeftMenuComponent上。

要使此工作正常,不需要将属性重新分配给组件。您可以简单地将服务的属性直接绑定到模板中,如下所示:

代码语言:javascript
复制
 <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属性而不是分配,如下所示:

代码语言:javascript
复制
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
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47740365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档