【问题标题】:Angular2: Updating and sharing data between componentsAngular2:在组件之间更新和共享数据
【发布时间】:2017-06-26 07:58:48
【问题描述】:

我正在尝试制作如下所示的内容:

寻找一种方法,让服务在必要时将最新数据提供给订阅的组件。例如:Component3 将更改写入 API > Component1 和 Component2 必须获取最新数据。

目前,这两个组件都订阅了服务返回的 observable,如果两者都呈现,这会导致 2 个 API 请求。这感觉不对。据我了解,这些组件应该被提供数据,而不是自己请求数据。需要明确的是:此服务返回的数据始终在 Component1 中使用,而 Component2 是可选渲染的。

这里有一些 sn-ps 和一些我到目前为止所做的描述:

Service 通过 HTTP 从 API 获取数据。 Component1Component2 订阅了 Service 返回的 observable:

import { Injectable } from "@angular/core";
import { Http } from "@angular/http";

import 'rxjs/add/operator/map';

@Injectable()

export class GroupService{
    constructor(private _http: Http){}

    getGroups(){
        return this._http.get('/assets/groups.json')
            .map((res) => {
                return res.json();
            });
    }
}

Component1Component2在功能上基本相同。这是其中之一:

import { Component } from '@angular/core';
import { router } from '../../app.router';
import { GroupService } from '../../services/group.service';
import { Group } from '../../interfaces/group.interface';

@Component({
    selector: 'app-sidebar',
    templateUrl: './sidebar.component.html',
    styleUrls: ['./sidebar.component.scss'],
})

export class SidebarComponent
{
    router;
    groups: Group[];

    constructor(private _groupService: GroupService){
        this.router = router;
        this.getGroups();
    }

    getGroups(){
        this._groupService.getGroups()
            .subscribe((groups) => {
                this.groups = groups;
            });
    }
}

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    与 seidme 的方法略有不同,我个人更喜欢:

    GroupService 中设置一个数据流并在您的组件中使用它。

    服务:

    import { Injectable } from "@angular/core";
    import { Http } from "@angular/http";
    import { BehaviorSubject } from 'rxjs/BehaviorSubject';
    import { Observable } from 'rxjs/Observable';
    
    import 'rxjs/add/operator/map';
    
    @Injectable()
    export class GroupService {
        private groupSource = new BehaviorSubject<any>({});
        public group$: Observable = this.groupSource.asObservable();
    
        constructor(private _http: Http) {}
    
        getGroups() {
            this._http.get('/assets/groups.json')
                .map((res) => {
                    return res.json();
                })
                .subscribe((groups) => this.groupSource.next(groups));
        }
    }
    

    然后在你的组件中,这样做:

    import { Component, OnInit } from '@angular/core';
    import { router } from '../../app.router';
    import { GroupService } from '../../services/group.service';
    import { Group } from '../../interfaces/group.interface';
    import { Observable } from 'rxjs/Observable';
    
    @Component({
        selector: 'app-sidebar',
        templateUrl: './sidebar.component.html',
        styleUrls: ['./sidebar.component.scss'],
    })
    
    export class SidebarComponent implements OnInit {
        router;
        groups: Observable;
    
        constructor(private _groupService: GroupService){
            this.router = router;
        }
    
        ngOnInit {
            this.groups = this._groupService.group$;
        }
    }
    

    然后在您的模板中,使用async 管道:{{ groups | async }}。它将负责为您订阅(和处置)可观察对象。

    现在,当您从任何组件调用GroupService.getGroups() 时,所有其他组件都会自动更新。

    另外,使用OnInit 比在构造函数中做一些事情更可取,参见Difference between Constructor and ngOnInit

    【讨论】:

    • 这正是我所需要的。谢谢。
    【解决方案2】:

    使用BehaviorSubject as a delegate 可能是您的用例最方便的选择。在服务中注册BehaviorSubject,并在这些组件中的任何一个请求新数据时需要更新的所有组件中订阅它。

    服务应该是这样的:

    @Injectable()
    export class GroupService {
    
        groupsSource: BehaviorSubject<any> = new BehaviorSubject(null);
    
        constructor(private _http: Http) { }
    
        getGroups(): void {
            this._http.get('/assets/groups.json')
                .map((res) => res.json())
                .subscribe((groups) => this.groupsSource.next(groups)); // Update all components subscribed to the BehaviorSubjet
        }
    }
    

    组件1,请求新数据:

    export class Component1 implements OnInit {
    
        groups: any;
    
        constructor(private _groupService: GroupService) { }
    
        ngOnInit() {
            this._groupService.groupsSource.subscribe((groups) => {
                this.groups = groups;
            });
    
            this._groupService.getGroups();
        }
    }
    

    组件 2,自动更新:

    export class Component2 implements OnInit {
    
        groups: any;
    
        constructor(private _groupService: GroupService) { }
    
        ngOnInit() {
            this._groupService.groupsSource.subscribe((groups) => {
                this.groups = groups;
            });
        }
    }
    

    使用BehaviorSubject,您无需订阅即可获得它所持有的最新值:

    export class Component3 implements OnInit{
    
        groups: any;
    
        constructor(private _groupService: GroupService) { }
    
        ngOnInit() {
            this.groups = this._groupService.groupsSource.getValue();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-25
      • 2018-04-10
      • 2016-05-18
      • 2017-09-29
      • 2019-08-07
      • 2020-08-31
      相关资源
      最近更新 更多