问题
Could someone please explain what\'s behind the following behavior?
Say we have an Angular 2 component that has a _model object. Then in the template we have this:
<form>
<input type=\"text\" class=\"form-control\" required [(ngModel)]=\"_model.firstName\" ngControl=\"test2\" #myInput >
<br>Class: {{myInput?.className}}
</form>
The _model is available from the beginning being created from scratch in ngOnInit(). The input field is properly populated with the _model.firstName variable and the line:
<br>Class: {{myInput?.className}}
correctly renders the following in the template:
Class: form-control ng-untouched ng-pristine ng-invalid.
So far so good. What confuses me is that the moment I add *ngIf and I change the input field to
<input *ngIf=\"_model\" type=\"text\" class=\"form-control\" required [(ngModel)]=\"_model.firstName\" ngControl=\"test2\" #myInput >
The double curly braces interpolation stops working because apparently the local myInput variable doesn\'t get initialized even when nothing else in the code changes, the _model object is still created in onNgInit() and the input field is still working properly. The only thing that the {{myInput?.className}} renders is
Class:
Can someone explain what\'s going on and/or point me to the correct piece of documentation for this?
EDIT:
Here\'s a Plunker that shows the issue in question.
Created bug report https://github.com/angular/angular/issues/8087
回答1:
We can reference a local template variable on the same element, on a sibling element, or on any child elements. -- ref
*ngIf becomes/expands to
<template [ngIf]="_model">
<input type="text" class="form-control" required [(ngModel)]="_model.firstName"
ngControl="test1" #myInput>
</template>
So local template variable #myInput can only be referenced inside the template block (i.e., sibling and/or child elements). Hence you would have to put any HTML that wants to reference the local template variable inside the template:
<template [ngIf]="_model">
<input type="text" class="form-control" required [(ngModel)]="_model.firstName"
ngControl="test1" #myInput >
<br>Class (this works): {{myInput?.className}}
</template>
Plunker
If you need to show something outside the template block related to the input, use @ViewChildren('myInput') list:QueryList<ElementRef> and then subscribe to changes:
ngAfterViewInit() {
this.list.changes.subscribe( newList =>
console.log('new list size:', newList.length)
)
}
See more QueryList methods in the API doc.
来源:https://stackoverflow.com/questions/36642487/ngif-and-local-template-variables