2

I have a situation where I was to replace

@ViewChild(Foo, { static: true }) foo!: Foo;

with a version that gets several Foo in a list.

The expected solution is

@ViewChildren(Foo, { static: true }) foos!: QueryList<Foo>;

but @ViewChildren doesn’t support static.

Is there any work-around here?

The use-case is that I have something like this:

@ViewChild(Foo, { static: true }) foo!: Foo;

ngOnInit(): void {
  onFooInit(this.foo);
}

ngAfterViewInit(): void {
  afterViewFooInit(this.foo);
}

and I need it to become

@ViewChildren(Foo, { static: true }) foos!: QueryList<Foo>;

ngOnInit(): void {
  this.foos.forEach(onFooInit);
}

ngAfterViewInit(): void {
  this.foos.forEach(afterViewFooInit);
}

where onFooInit and afterViewFooInit are black-box library functions whose documentation says to call them in ngOnInit and ngAfterViewInit, respectively, noting that { static: true } is necessary to do so. (I have tested this, and yes, there are errors without { static: true }.)

I tried some hackery with @ViewChild(Foo, { static: true }) set foo(foo: Foo) { this.foos.push(foo); }, which unsurprisingly went nowhere, and I tried to create my own custom decorator that internally called ViewChild on each match of the selector, which I couldn’t get working. One thing I know I could do is just use ViewChild on each individual thing I want to include in the list, and then hard-code the actual list creation from those, but I want to re-use this code in several components which is going to get painful real fast.

Then I realized this should really be a directive, but the ElementRef in the directive has the same problems, being undefined in ngOnInit (I guess it isn’t static). The alternative to a directive is a wrapping component, but then I have to worry about all the inputs which is a huge pain. Probably better than the hard-coded polymorphic list, though.

I am open to suggestions on better ways to avoid this kind of initialization boilerplate on each of these components (that are very similar to one another, just with slightly different fields in each case).

KRyan
  • 7,308
  • 2
  • 40
  • 68

0 Answers0