首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角度6观测数据从第3次发球开始变化

角度6观测数据从第3次发球开始变化
EN

Stack Overflow用户
提问于 2018-06-21 14:22:27
回答 2查看 3.9K关注 0票数 0

一定是很基本的东西,但我被困住了。

简而言之,我有三个服务: service0、service1、service3。Service1存储的数据和服务2&3与它一起工作。

我想订阅来自这两个服务的service1数据属性的更改。我该怎么做?

示例:

代码语言:javascript
复制
export class Service0 implements OnDestroy {
  constructor(private service1: Service1) { }
  add(data): boolean { this.service1.addData(data); }
}

export class Service1 implements OnDestroy {
  data: Data;
  constructor() { }
  get data() { return this.data }

  addData(data) {
     if (this.servers.findIndex(el => el.hostname === s.hostname) === -1){    
        this.data.push(s);
     }
  }
}

export class Service2 implements OnDestroy {
  data: Data;
  constructor(private service1: Service1) { this.data = this.service1.data; }
}

更新:--我尝试过这样做,它应该可以工作(数据服务):

代码语言:javascript
复制
import {Observable, of} from 'rxjs';

export class Service1 {
  data: Data[];

  constructor() { }
  get data() { return this.data }

  addData(data) {
     if (this.servers.findIndex(el => el.hostname === s.hostname) === -1){    
        this.data.push(s);
     }
  }

  getData(): Observable<Data[]> {
     return of(this.data)
  }
}

export class Service2 implements OnDestroy {
 data: Data[];
 constructor(private service1: Service1) { 
    this.service1.getData().subscribe(data=>{
       this.data = data
       console.log(this.data)
    })  
 }
}

一旦添加了对象,它就会触发,但在本例中,console.log(this.data)只在浏览器控制台中显示对象数组,而JSON.stringify(this.data)则试图调用属性--显示对象是空的。仍然喜欢这个解决方案,但不知道为什么会发生这种情况?

同时,现在我使用dataChanges = new Subject();Service1中更改数据后发出一个事件,然后

代码语言:javascript
复制
this.servers1.serversChanges.subscribe(() => {
  this.data = this.service1.getData();
});

去拿它。在这种情况下,它起作用了。

EN

回答 2

Stack Overflow用户

发布于 2018-06-21 14:57:46

为了订阅某件东西,这件事必须是可观察的。为此,我们使用诸如Rxjs这样的库。有许多可观察到的rxjs,例如我们的主题、BehaviorSubjects、AsyncSubjects等。您可以在这里更多地阅读rxjs

下面的示例展示了如何实现一个简单的可观察数据服务!

代码语言:javascript
复制
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

Injectable()
export class Service0  {
    data: BehaviorSubject<string[]>;
    constructor() {
        this.data = new BehaviorSubject<string[]>([]);
    }
    getData() {
        // Logic to get data from an http call
        // On Successful response
        this.data.next(responseData);
    }
}

现在,您可以在任何其他服务、组件等上注入该服务,并轻松地订阅数据。

代码语言:javascript
复制
import { Injectable } from '@angular/core';
import { Service0 } from '../service0.ts';

Injectable()
export class Service1  {
    data: string[];
    constructor(private service0: Service0) {
        service0.data.subscribe(data => {
            this.data = data;
        });
    }
    dataFunction() {
        // do stuff with data
    }
}

现在,您的第二服务将始终拥有将从Service0提供的最新数据。

我还想指出,如果您在组件中使用该功能,那么在不存在任何数据泄漏的情况下,真正做到这一点的最佳实践是取消订阅可观察到的内容。就像这样:

代码语言:javascript
复制
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { Service0 } from '../service0.ts';

@Component({
    selector: 'my-component',
    templateUrl: './my-component.component.html',
    styleUrls: ['./my-component.component.scss']
  })
export class MyComponent implements OnInit, OnDestroy  {
    data: string[];
    dataSubscription: Subscription;
    constructor(private service0: Service0) { }
    ngOnInit() {
        this.dataSubscription = this.service0.data.subscribe(data => {
            this.data = data;
        });
    }
    ngOnDestroy() {
        this.dataSubscription && this.dataSubscription.unsubscribe();
    }
}

您不需要在Singleton服务中这样做,因为您在构造函数中订阅,并且该订阅只在该服务的生存期内持续。该构造函数将只被调用一次。如果该服务不是单个实例,那么您必须实现相同的逻辑,因为您可能需要创建该服务的多个实例。在这里读到关于单身汉的Angular.io。我希望我能给你一个答案来帮助你完成你的工作。如有任何问题,请随时与我联系。

干杯

票数 2
EN

Stack Overflow用户

发布于 2018-06-21 14:35:58

好的,我在注释中给出了一些想法,但是下面是代码:

代码语言:javascript
复制
export class Service0 implements OnDestroy {
    constructor(private service1: Service1) {
        // In case when you only inform without passing data
        this.service1.dataChanges.subscribe(() => {
            // This service doesn't have 'data' member so do something else
        });

        // With passed data
        this.service1.dataChanges.subscribe((data) => {
            // This service doesn't have 'data' member so do something else
        });
    }

    add(data): boolean {
        this.service1.addData(data); // Could be changed now to use that setter
    }
}

export class Service1 implements OnDestroy {
    _data: Data;
    dataChanges = new Subject();

    constructor() {
    }

    get data() {
        return this._data;
    }

    set data(value) {
        this._data = value;
        this.dataChanges.next(); // or even pass here new value
    }
}

export class Service2 implements OnDestroy {
    data: Data;

    constructor(private service1: Service1) {
        this.data = this.service1.data;

        // In case when you only inform without passing data
        this.service1.dataChanges.subscribe(() => {
            this.data = this.service1.data;
        });

        // With passed data
        this.service1.dataChanges.subscribe((data) => {
            this.data = data;
        });
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50970878

复制
相关文章

相似问题

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