snippettypescriptangularCritical
How can I select an element in a component template?
Viewed 0 times
howcomponentelementtemplatecanselect
Problem
Does anybody know how to get hold of an element defined in a component template? Polymer makes it really easy with the
I was just wondering how to go about it in Angular.
Take the example from the tutorial:
How do I catch hold or get a reference of the
$ and $$.I was just wondering how to go about it in Angular.
Take the example from the tutorial:
import {Component} from '@angular/core';
@Component({
selector:'display',
template:`
My name : {{myName}}
`
})
export class DisplayComponent {
myName: string = "Aman";
updateName(input: String) {
this.myName = input;
}
}How do I catch hold or get a reference of the
p or input element from within the class definition?Solution
Instead of injecting
element
StackBlitz example
descendants
@ContentChildren()
@ContentChildren(SomeType) contentChildren;
ngOnInit() {
this.viewChildren.changes.subscribe(changes => console.log(changes));
this.contentChildren.changes.subscribe(changes => console.log(changes));
}
constructor(private elRef:ElementRef) {}
ngAfterViewInit() {
var div = this.elRef.nativeElement.querySelector('div');
console.log(div);
}
// for transcluded content
ngAfterContentInit() {
var div = this.elRef.nativeElement.querySelector('div');
console.log(div);
}
}
`
get arbitrary projected content
See Access transcluded content
ElementRef and using querySelector or similar from there, a declarative way can be used instead to access elements in the view directly:
@ViewChild('myname') input;
element
ngAfterViewInit() {
console.log(this.input.nativeElement.value);
}
StackBlitz example
- @ViewChild() supports directive or component type as parameter, or the name (string) of a template variable.
- @ViewChildren() also supports a list of names as comma separated list (currently no spaces allowed
@ViewChildren('var1,var2,var3')).
- @ContentChild() and @ContentChildren() do the same but in the light DOM (`
projected elements).
descendants
@ContentChildren()
is the only one that allows you to also query for descendants
@ContentChildren(SomeTypeOrVarName, {descendants: true}) someField;
{descendants: true} should be the default but is not in 2.0.0 final and it's considered a bug
This was fixed in 2.0.1
read
If there are a component and directives the read parameter allows you to specify which instance should be returned.
For example ViewContainerRef that is required by dynamically created components instead of the default ElementRef
@ViewChild('myname', { read: ViewContainerRef }) target;
subscribe changes
Even though view children are only set when ngAfterViewInit() is called and content children are only set when ngAfterContentInit() is called, if you want to subscribe to changes of the query result, it should be done in ngOnInit()
https://github.com/angular/angular/issues/9689#issuecomment-229247134
@ViewChildren(SomeType) viewChildren;@ContentChildren(SomeType) contentChildren;
ngOnInit() {
this.viewChildren.changes.subscribe(changes => console.log(changes));
this.contentChildren.changes.subscribe(changes => console.log(changes));
}
direct DOM access
can only query DOM elements, but not components or directive instances:
export class MyComponent {constructor(private elRef:ElementRef) {}
ngAfterViewInit() {
var div = this.elRef.nativeElement.querySelector('div');
console.log(div);
}
// for transcluded content
ngAfterContentInit() {
var div = this.elRef.nativeElement.querySelector('div');
console.log(div);
}
}
`
get arbitrary projected content
See Access transcluded content
Context
Stack Overflow Q#32693061, score: 1257
Revisions (0)
No revisions yet.