Rxjs:防止从服务外向主题推送数据

Rxjs : prevent pushing data to subjects from outisde the service

Within my anguular app , i ve this service :

@Injectable()
export class myService{

  myBehaviouSubject= new BehaviorSubject("");


  setData(){
     this.myBehaviouSubject.next("123");
  }

}

在我的 app.component 中,我可以获取值,但我想保留它 只读 或仅可编辑在服务本身内部,我想防止从组件 (.next('DATA'))

推送任何数据
    @Component({

    })
    export class AppComponent implements OnInit {

      constructor(public myService : MyService) { }

    getData(){
      // GET VALUE
      this.myService.myBehaviouSubject.value
    }

    unwantedMethodToSetValue(){
           // SET VALUE -> i want to prevent this
           this.myService.myBehaviouSubject.next("unwanted value")

    }

}

建议 ?

您只能通过将其声明为 class 的私有字段来保留可观察的内部服务。

@Injectable()
export class myService {

  private myBehaviouSubject = new BehaviorSubject("");

  // Use this observable inside the app component class.
  myBehaviouSubjectObservable = myBehaviouSubject.asObservable();

  setData() {
    this.myBehaviouSubject.next("123");
  }
}

@Component({

})
export class AppComponent implements OnInit {

  constructor(public myService: MyService) {}

  getData() {
    // You can subscribe to observable and can get value here
    this.myService.myBehaviouSubjectObservable.subscribe((value) => {
      console.log(value);
    })
  }

  unwantedMethodToSetValue() {
    // SET VALUE -> you cannot do this here now.
    this.myService.myBehaviouSubject.next("unwanted value")

  }

}

传统答案:如果您 return 将 Subject 作为可观察对象,则不允许调用 .next()。

但在您的情况下,您还希望无需订阅即可直接访问当前值,因此您也可以为此添加一个 getter。

@Injectable()
export class myService{

  private readonly myBehaviouSubject = new BehaviorSubject("");


  setData(){
     this.myBehaviouSubject.next("123");
  }
  public get myObservable$(): Observable<string>{
    return this.myBehaviourSubject;
  }
  public get currentValue(): string{
    return this.myBehaviourSubject.value;
  }

}

使用属性访问修饰符:

@Injectable()
export class MyService{
  private myValueSubject: BehaviorSubject<string> = new BehaviorSubject<string>("");
  public readonly myValueObservable: Observable<string> = this.myValueSubject.asObservable();

  public setData() {
     this.myValueSubject.next("123");
  }
  public getData(): string {
    return this.myValueSubject.value;
  }
}

MyService 的实例将没有可公开访问的主题。

我通常会尽量避免使用 getData 之类的方法,而倾向于订阅相关的可观察对象。如果我发现自己在编写这些类型的方法,这就是重新评估我的架构的警告标志。如果您只想存储一个值并 get/set 使用方法,请使用普通的旧私有 属性。如果您仅通过 getData()

之类的方法获得价值,则该主题的全部目的都会被打败

查看 typescript 类 的文档,其中讨论了访问修饰符:https://www.typescriptlang.org/docs/handbook/classes.html

https://stackblitz.com/edit/angular-protected-rxjs-subject

在此解决方案中希望能满足您的需求:

  • 注意没有订阅
  • 正在获取手动处理的更新
  • 属性 'myBehaviourSubject' 是私人的,只能访问
    在 class 'TestService'.