Rx js: предотвращение передачи данных субъектам из службы - PullRequest
0 голосов
/ 20 февраля 2020
Within my anguular app , i ve this service :

@Injectable()
export class myService{

  myBehaviouSubject= new BehaviorSubject("");


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

}

Внутри моего app.component я могу получить значение, но я хочу сохранить его только для чтения или редактировать только внутри самой службы, я хочу предотвратить в pu sh любые данные из компонента (.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")

    }

}

Предложения?

Ответы [ 4 ]

2 голосов
/ 20 февраля 2020

Используйте модификаторы доступа к свойству:

@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, предпочитающего подписки к соответствующей наблюдаемой. Если я когда-либо пишу такие методы, это предупреждающий флаг для переоценки моей архитектуры. Если вы просто хотите сохранить значение и получить / установить его с помощью методов, используйте простое старое частное свойство. Вся цель предмета побеждена, если вы когда-либо получаете значение только с помощью метода, подобного getData()

Ознакомьтесь с документацией для классов машинописи, в которой рассматриваются модификаторы доступа: https://www.typescriptlang.org/docs/handbook/classes.html

2 голосов
/ 20 февраля 2020

Вы можете сохранить наблюдаемый внутренний сервис, только объявив его как личное поле класса.

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

  }

}
0 голосов
/ 20 февраля 2020

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

в этом решении, которое, я надеюсь, удовлетворит ваши потребности:

  • помните, что подписка отсутствует
  • выборка обновлений обрабатывается вручную
  • Свойство 'myBehaviourSubject' является закрытым и доступно только
    в классе 'TestService'.
0 голосов
/ 20 февраля 2020

Традиционный ответ: если вы возвращаете тему как наблюдаемую, вы запрещаете вызовы .next ().

Но в вашем случае вам также нужен прямой доступ к текущему значению без подписки, так что вы можете для этого тоже добавьте геттер.

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

}
...