当前位置: 首页 > 知识库问答 >
问题:

Angular2:在组件之间更新和共享数据

寿飞飙
2023-03-14

寻找一种方法,使服务在必要时将最新数据提供给订阅的组件。例如:组件 3 将更改写入 API

以下是一些片段和一些描述,说明到目前为止我所做的工作:

该服务通过HTTP从API获取数据。组件1和组件2订阅了服务返回的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();
            });
    }
}

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;
            });
    }
}

共有2个答案

张智
2023-03-14

使用BehaviorSubject作为委托可能是您的用例最方便的选择。在服务中注册< code>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;
        });
    }
}
export class Component3 implements OnInit{

    groups: any;

    constructor(private _groupService: GroupService) { }

    ngOnInit() {
        this.groups = this._groupService.groupsSource.getValue();
    }
}
龚勇锐
2023-03-14

这是一种与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$;
    }
}

然后在模板中,使用异步管道:{{ 组 |异步 }}。它将负责为您订阅(和处置)可观察量。

现在,每当您从任何组件调用< code > group service . get groups()时,所有其他组件都会自动更新。

此外,使用 OnInit 比在构造函数中执行操作稍微好一些,请参阅构造函数和 ngOnInit 之间的区别。

 类似资料:
  • 我正在使用angular2开发一个应用程序。我有一个场景,需要在路由时(使用router.navigate())将复杂的数据(对象数组)从一个组件传递到另一个组件(它们不是父子关系,而是两个独立的组件)。我在谷歌上搜索过,大多数结果描述了父子组件的场景。我浏览了结果,找到了这些传递数据的方法。 1)创建共享服务2)通过路由参数 第二种方法适合我(尽管我不喜欢上面解释的复杂数据)。我无法使用共享服务

  • 问题内容: 我正在开发使用Meteor和React作为视图引擎的应用程序 考虑下图: 从另一个示例反应隐藏组件 当触发C4按钮单击事件时,我需要更改C2组件状态。由于他们没有直接关系,因此我无法直接从C4进入C2状态。 另一个示例是从Component提交表单并获取在另一个Component中声明的数据(输入字段的值)。 我知道可以通过一些技巧来解决此问题(例如,流星会话,通过每个组件传递数据,基

  • 我正在做一个phonegap应用程序,我不能在index.html和inappbrowser窗口之间共享数据。我尝试了这段代码,但它对我不起作用。 我还尝试使用localStorage,但只将inappbrowser的数据共享到index.js,而不是将index.js的数据共享到inappbrowser。

  • 在上一次谷歌IO上,谷歌发布了一些新arch组件的预览,其中之一是ViewModel。 在文档中,谷歌展示了该组件的一个可能用途: 一个活动中的两个或多个片段需要相互通信是很常见的。这绝不是小事,因为两个片段都需要定义一些接口描述,所有者活动必须将两者绑定在一起。此外,两个片段都必须处理另一个片段尚未创建或不可见的情况。 这个常见的痛点可以通过使用ViewModel对象来解决。想象一个主细节片段的

  • 在Angular 1.x.x中,您只需请求相同的服务,并以相同的实例结束,这使得在服务中共享数据成为可能。 现在在Angular 2中,我有了一个引用我的服务的组件。我可以读取和修改服务中的数据,这很好。当我试图在另一个组件中注入相同的服务时,似乎得到了一个新的实例。 我做错了什么?是模式本身有问题(使用服务共享数据)还是我需要将服务标记为单例(在应用程序的一个实例中)或其他? 我在 btw上 我

  • null 在列出的3个选项中,只有最后一个可以使用projectile(可能还有其他Emacs包)。但我需要能够访问/修改文件从Windows以及,所以这不是一个可行的选择。 有没有人为此找到好的解决方案?