Angular (9) совместное использование общего состояния между компонентами - PullRequest
0 голосов
/ 08 мая 2020

В текущем (2020) Angular у меня есть два компонента, которые предназначены для совместного использования состояния activeProject через службу. Для ApplicationProjectService у меня определено следующее:

private activeProjectSource = new BehaviorSubject(undefined);
activeProject$ = this.activeProjectSource.asObservable();

set activeProject(v: any) {
  this.activeProjectSource.next(v);
}

get activeProject() {
  return this.activeProjectSource.value;
}

Я использую BehaviorSubject в службе, так как я хочу, чтобы компоненты получали текущее значение при подписке без каких-либо изменений. Геттер / сеттер существует, потому что я делал другую привязку непосредственно к свойству службы, что, как я узнал, не рекомендуется.

Два родственных компонента, которые в конечном итоге прослеживаются до общего родителя, но я Я не использую @Input() или @Output() или какой-либо параметр, передаваемый в DOM:

this.appProjectService.activeProject$.subscribe(activeProject => {
  this.activeProject = activeProject;
});

Каждый компонент привязывается к свойству this.activeProject в соответствующем компоненте, используя [(ngModel)]:

<input type="checkbox" [(ngModel)]="activeProject.someProperty">

Вопрос

Если каждый компонент получил то, что, как я думал, было копией от activeProject до this.appProjectService.activeProject$.subscribe(), как работает изменение локального свойства в один компонент отражается в другом? В конце концов, это именно то поведение, которое я хочу, но не могу понять, почему оно работает. Есть ли какая-то передача по ссылке, которую я не понимаю в rx js observables?

Ответы [ 2 ]

1 голос
/ 08 мая 2020

Я знаю, что это должно быть в комментариях, но эта большая часть комментариев к письмам не принимается.

Забудьте на время о RxJS.

Теперь у вас есть getter и setter для вашей собственности.

Вы устанавливаете activeProjectValue в своем сервисе.

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

Если надо сломать ссылку, использовать по другому.

Также each component obtained what I thought was a copy of activeProject .... это означает, что они копируют по ссылке на объект.

Я знаю, вы знаете, как разбить ссылку, но это только для будущих зрителей

Чтобы разбить ссылку на объект, вы можете использовать JSON.parse(JSON.stringify(*ObjectName*)

В вашем примере

this.appProjectService.activeProject$.subscribe(activeProject => {
   this.activeProject = JSON.parse(JSON.stringify(activeProject));
});
1 голос
/ 08 мая 2020

s Если у вас 2 компонента, обе локальные переменные activeProject используют одну и ту же ссылку activeProject. ngModel привязан к свойству этой ссылки. Итак, это работает, потому что изменение в компоненте только обновляет свойство ссылки и не меняет ссылку. Вы даже можете использовать переменную activeProject, не заключая ее в BehaviorSubject.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...