S
S
Sergei Abramov2019-12-03 19:44:21
Angular
Sergei Abramov, 2019-12-03 19:44:21

Is it possible to somehow change the property of all instances of the class at once?

Good evening!
I am making a tree in angular, and I came across this question: is it possible to somehow change the property of all objects of the same class? There is a class:

export class Item {
public expand = false;
}

You need to change the expand of all objects at once. It is possible to run recursively through the tree with foreach and change each one individually, but maybe there is some kind of magic that would change everyone at once? There are a lot of elements.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry Luzanov, 2019-12-03
@PatriotSY

I think it would be more correct to create an ItemsTreeService service. In the service in the ReplaySubject, write the state - whether everything is collapsed. The component injects this service into itself and monitors isAllCollapsed. If you need to collapse everything - collapseAll()at the service, which will write a new value to our Observable property at the service.this.isAllCollapsedRef.next(true)

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

But I would not interfere with such behavior in the Item component if it is tied to business logic. It is better to make a separate module for the tree so that it can be reused. There is a ready-made tree: https://material.angular.io/components/tree/overview.

R
Robur, 2019-12-03
@Robur

Briefly: No.
Long:
1. You can pile up syntactic sugar to get, for example, `Item.expandAll()`, but inside there will be the same running through all objects.
2. You can put this property in the prototype so that it will be the same for everyone, and will change at once for everyone.
But all Item will always be either expand=true or expand=false, and there is somehow little sense in this.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question