Думаю правильнее будет создать сервис ItemsTreeService. В сервисе в ReplaySubject записать состояние - свернуто ли всё. Компонент инжектит в себя этот сервис и следит за isAllCollapsed. Если нужно всё свернуть -
collapseAll()
у сервиса, который будет
this.isAllCollapsedRef.next(true)
записывать новое значение в наше Observable свойство у сервиса.
@Injectable({
providedIn: "root"
})
export class ItemsTreeService {
private readonly isAllCollapsed$ = new ReplaySubject<boolean>(1);
public collapseAll() {
this.isAllCollapsed.next(true);
}
public isAllCollapsed() {
return this.isAllCollapsed$.asObservable();
}
}
@Component({
template: `
<div *ngIf="isExpanded | async">
// content
</div>
`
})
export class ItemTreeNodeComponent implements OnInit {
public readonly expandRef = new BehaviorSubject<boolean>(false);
public isExpanded: Observable<boolean>;
constructor(private readonly itemsTreeService: ItemsTreeService) {}
public ngOnInit() {
this.isExpanded = this.expandRef.asObservable().pipe(
combineLatest(this.itemsTreeService.isAllCollapsed()),
map(([expanded, allCollapsed]) => /* в зависимости от того, что вам пришло, решаете открыть вам ваш айтем или нет */)
);
}
public expand() {
this.expandRef.next(true);
}
public collapse() {
this.expandRef.next(false);
}
}
Но я бы не стал мешать подобное поведение в компонент Item, если он завязан на бизнесслогике. Лучше сделать отдельный модуль для дерева, чтобы его можно было переиспользовать. Есть готовое дерево:
https://material.angular.io/components/tree/overview.