Простой способ обработки состояния в Angular

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

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

Альтернатива

Есть другой способ сохранить ваш код чистым и пригодным для повторного использования.

Он работает, ничего не добавляя в ваше приложение, кроме rxjs, который уже есть.

Я склонен абстрагировать состояние от логики вашего представления, таким образом, состояние — это то, как выглядят данные. Затем, когда у вас есть несколько компонентов, независимо от того, насколько они вложены, вы можете прослушивать это состояние и вызывать действия, которые необходимо выполнить в этом состоянии.

Переходим к коду:

// user.state.ts
export interface User {
  name: string;
  avatarUrl: string;
}

@Injectable({
  providedIn: 'root'
})
export class UserState {
  private user = new BehaviorSubject<User>({ 
    name: 'John Doe', 
    avatarUrl: 'https://example.com/avatar.png' 
  });

  user$ = this.user.asObservable();

  updateUser(user: User) {
    this.user.next(user);
  }
}
// any.component.ts
@Component({
  selector: ‘app-user-icon’,
  template: `
    <ng-container *ngIf="user$ | async as user">
       <img [src]="user.avatarUrl">
       {{ user.name }}
    </ng-container>
  `
})
export class UserIconComponent {
  user$ = this.userState.user$;

  constructor(private userState: UserState) {}
}

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

К вашему сведению, асинхронный канал автоматически отменяет подписку

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

// Саймон