简体   繁体   English

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

}

Inside my app.component , im able to get the value , but i want to keep it readonly or editable only inside the service itself , i want to prevent to push any data from component ( .next('DATA') )在我的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")

    }

}

Suggestions ?建议?

You can keep the observable inside service only by declaring it as private field of a class.您只能通过将其声明为类的私有字段来将 observable 保留在服务内部。

 @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") } }

Use property access modifiers:使用属性访问修饰符:

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

Instances of MyService will not have a publicly accessible subject. MyService实例没有可公开访问的主题。

I usually try to avoid a method like getData , favoring subscriptions to the related observable.我通常会尽量避免使用像getData这样的方法,而是倾向于订阅相关的 observable。 If I ever find myself writing those kinds of methods, it's a warning flag to re-evaluate my architecture.如果我发现自己正在编写这些类型的方法,那么重新评估我的架构是一个警告标志。 If you just want to store a value and get/set it with methods, use a plain old private property.如果您只想存储一个值并使用方法获取/设置它,请使用普通的旧私有属性。 The entire purpose of the subject is defeated if you are only ever getting the value through a method like getData()如果您只是通过getData()类的方法获取值,则该主题的整个目的就失败了

Check out the documentation for typescript classes, which discusses access modifiers: https://www.typescriptlang.org/docs/handbook/classes.html查看 typescript 类的文档,其中讨论了访问修饰符: https : //www.typescriptlang.org/docs/handbook/classes.html

The traditional answer : If you return the Subject as an observable, you disallow .next() calls.传统答案:如果将 Subject 作为可观察对象返回,则不允许 .next() 调用。

But in your case, you also want direct access to the current value without subscribing, so you could add a getter for that too.但是在您的情况下,您还希望无需订阅即可直接访问当前值,因此您也可以为此添加一个 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;
  }

}

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

in this solution which I hope meet you needs:在这个解决方案中,我希望满足您的需求:

  • be aware that there is no subscription请注意,没有订阅
  • fetching updates handled manually获取手动处理的更新
  • Property 'myBehaviourSubject' is private and only accessible属性“myBehaviourSubject”是私有的,只能访问
    within class 'TestService'.在“TestService”类中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM