Почти всегда, если вы ищете примеры межкомпонентной связи через сервисы, примеры используют RxJS внутри сервиса (теперь это тоже могут быть сигналы). Однако, похоже, в этом нет необходимости. Например, даже в случае приведенного ниже сервиса оба компонента смогут видеть изменения счетчика без использования RxJS или сигналов.
Есть ли обратная сторона отказа от использования RxJS или Signals в этом случае? Я понимаю, что использование RxJS или Signals — это своего рода предписанный способ делать что-то в Angular, и это веская причина для этого, но мне интересно, есть ли реальная причина помимо этого. Может ли это вызвать какие-либо проблемы или ошибки?
Пример сервиса ниже и вот образец Stackblitz.
Услуга:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class MyService {
private counter: number = 0;
increment() {
this.counter += 1;
}
getValue() {
return this.counter;
}
}
Компонент1:
import { Component } from '@angular/core';
import { MyService } from './MyService';
@Component({
selector: 'component1',
standalone: true,
template: `
<h1>Component 1</h1>
Current Value: {{ valueFromService }}
<button (click) = "increment()">Click to increment</button>
`,
})
export class Component1 {
constructor(private myService: MyService) {}
get valueFromService() {
return this.myService.getValue();
}
increment() {
this.myService.increment();
}
}
Компонент 2:
import { Component } from '@angular/core';
import { MyService } from './MyService';
@Component({
selector: 'component2',
standalone: true,
template: `
<h1>Component 2</h1>
Current Value: {{ valueFromService }}
`,
})
export class Component2 {
constructor(private myService: MyService) {}
get valueFromService() {
return this.myService.getValue();
}
}





Использование Observables хорошо сочетается с OnPush ChangeDetectionStrategy, которая обычно положительно влияет на производительность во время выполнения. Это также упрощает работу с производными состояниями, обработку нескольких одновременных обновлений и запуск побочных эффектов в качестве реакции на обновления состояния.
Ваш пример работает, пока компоненты используют ChangeDetectionStrategy по умолчанию. Давайте подробнее рассмотрим очень упрощенное и не очень точное объяснение того, что происходит, когда пользователь нажимает кнопку увеличения:
Таким образом, обновление значения услуги и обновление отображаемого значения как бы разделены. Если значение обновляется в результате чего-то, что Zone.js не может перехватить (например, awync/await), представление не отразит изменения. Стоит отметить, что события могут происходить довольно часто, и проверка каждого компонента по каждому событию может стать довольно сложной задачей. Вот почему рекомендуется использовать OnPush ChangeDetectionStrategy.
Не вдаваясь в подробности, при использовании OnPush Angular пропускает проверку этого компонента и всех его дочерних элементов, если только некоторые входные данные не изменены или компонент не помечен для проверки, например, звоню ChangeDetectorRef.markForCheck(). Это обычная схема получения наблюдаемого из сервиса и привязки к нему в шаблоне через канал async, и канал вызывает markForCheck каждый раз, когда Observable излучает значение. Таким образом, хотя цикл обнаружения изменений все еще необходимо запустить, обновление наблюдаемого значения делает компонент проверенным, а те компоненты, которые не имеют изменений, не будут проверяться вообще.
Что касается производных состояний и побочных эффектов, давайте представим, что у нас есть два сервиса A и B, и когда значение обновляется в A, нужно что-то сделать в B. Без Observables, которые потребовали бы внедрения B в A, и что, если у нас есть десятки таких соединений ? Довольно быстро становится грязно. То же самое справедливо и для компонентов: довольно распространенная ситуация, когда перед рендерингом значения его необходимо преобразовать, объединить с другим и только потом визуализировать. Хотя это можно сделать внутри геттера, запускать их в каждом цикле CD — пустая трата ресурсов.
И последнее: некоторые API Angular представлены в виде Observable, например, реактивные формы, события маршрутизатора, HttpClient, поэтому их проще встроить в свои собственные вещи, если они также основаны на Observable.
Спасибо за подробное объяснение. Другая причина, которую упомянул коллега, заключается в том, что команда Angular надеется в какой-то момент устранить Zone.js, и использование реактивных библиотек (RxJS, Signals), вероятно, поможет в будущем защититься от этого.