ViewChildren class

Declares a reference to multiple child nodes in a component's template.

The annotated List is replaced when the DOM is updated.

The annotation requires a selector argument:

  • If the argument is a Type, directives or components with that exact type, or injectable services available on directives or components will be bound.
  • If the argument is a String, the string is interpreted as a list of comma-separated selectors. For each selector, an element containing the matching template variable (e.g. #child) will be bound.

Optionally, a read parameter may be specified in order to read a specific property on the bound directive, component, or element. Common values include the types TemplateRef, ViewContainerRef, Element, or the string value of Directive.exportAs (when it is ambiguous what node to select from the template).,

View children are set before the ngAfterViewInit method is invoked, and may be updated before the ngAfterViewChecked method is invoked. The preferred method for being notified of the list instance changing is creating a setter instead of using a field.

Examples

With a Type selector:

@Component(
  selector: 'child-cmp',
  template: '<p>child</p>'
)
class ChildCmp {
  void doSomething() {}
}

@Component(
  selector: 'some-cmp',
  template: '''
    <child-cmp></child-cmp>
    <child-cmp></child-cmp>
    <child-cmp></child-cmp>
  ''',
  directives: [ChildCmp],
)
class SomeCmp implements AfterViewInit {
  @ViewChildren(ChildCmp)
  List<ChildCmp> children;

  @override
  void ngAfterViewInit() {
    // children are set
    for (var child in children) {
      child.doSomething();
    }
  }
}

With a String selector:

@Component(
  selector: 'child-cmp',
  template: '<p>child</p>',
)
class ChildCmp {
  void doSomething() {}
}

@Component(
  selector: 'some-cmp',
  template: '''
    <child-cmp #child1></child-cmp>
    <child-cmp #child2></child-cmp>
    <child-cmp #child3></child-cmp>
  ''',
  directives: [ChildCmp],
)
class SomeCmp implements AfterViewInit {
  @ViewChildren('child1, child2, child3')
  List<ChildCmp> children;

  @override
  void ngAfterViewInit() {
    // Initial children are set
    for (var child in children) {
      child.doSomething();
    }
  }
}

Using a setter for update notifications:

@Component(
  selector: 'child-cmp',
  template: '<p>child</p>',
)
class ChildCmp {
  void doSomething() {}
}

@Component(
  selector: 'some-cmp',
  template: '''
    <child-cmp *ngIf="condition1" #child1></child-cmp>
    <child-cmp *ngIf="condition2" #child2></child-cmp>
    <child-cmp *ngIf="condition3" #child3></child-cmp>
  ''',
  directives: [ChildCmp],
)
class SomeCmp {
  @Input()
  bool condition1 = false;

  @Input()
  bool condition2 = false;

  @Input()
  bool condition3 = false;

  @ViewChildren('child1, child2, child3')
  set children(List<ChildCmp> children) {
    // Note above that the child components may or may not be created (they
    // are guarded with '*ngIf'). This setter is called every time the
    // visible children change (including the initial visibility, so we do
    // not need 'ngAfterViewInit').
    for (var child in children) {
      child.doSomething();
    }
  }
}

Reading an HTML element using read:

@Component(
  selector: 'child-cmp',
  template: '<p>child</p>',
)
class ChildCmp {
  void doSomething() {}
}

@Component(
  selector: 'some-cmp',
  template: '''
    <child-cmp #child1></child-cmp>
    <child-cmp #child2></child-cmp>
    <child-cmp #child3></child-cmp>
  ''',
  directives: [ChildCmp],
)
class SomeCmp {
  @ViewChildren('child1, child2, child3', read: Element)
  List<Element> children;
}

WARNING: Queries such as ViewChildren, ContentChildren and related are only meant to be used on static content in the template. For example writing a custom structural directive (like *ngIf) that changes the structure of the DOM in custom ways will not work properly with queries and could cause runtime type errors.

WARNING: There is a known issue (b/129297484) where, when used in combination with an NgFor (or a custom directive that supports moving embedded views) this field or setter may not be updated. For details see go/angular-dart/dev/template-queries.

Annotations
  • @Target({TargetKind.field, TargetKind.setter})

Constructors

ViewChildren(Object selector, {Object? read})
const

Properties

descendants bool
Whether to query only direct children (false) or all children (true).
finalinherited
first bool
Whether to only query the first child.
finalinherited
hashCode int
The hash code for this object.
no setterinherited
read Object?
The DI token to read from an element that matches the selector.
finalinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
selector Object
Either the class Type or selector String.
finalinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited