13

this is my template:

<ng-template #template>
    <input #newimg  type="file" class="col-md-10" (change)="fileChange($event)"/>
</ng-template>

I cant get reference to #newimg when its inside ng-template(it works fine if i change ng-template to div!)

@ViewChild('newimg') img: ElementRef; //doesnt work

I need to set its value to empty after image uploaded but its always undefined.

Veto
  • 165
  • 1
  • 2
  • 7

2 Answers2

4

<ng-template> is not added to the DOM, it exists only in JavaScript code, when the Application runs. Only when it is stamped using for example a structural directive like *ngFor or *ngIf, the content is actually created in the DOM and bindings, components, directives, ... are instantiated.

Therefore without stamping, there won't be any #template to query for.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • but he's passing it to ngx-bootstrap and bootstrap modal creates an embedded view using this template – Max Koretskyi Nov 22 '17 at 07:57
  • Then a parent of that dialog should be able to query it using `@ContentChild('template') ...`. – Günter Zöchbauer Nov 22 '17 at 07:58
  • there's no content projection involved, the template is passed directly to the `show` method of bootstrap https://valor-software.com/ngx-bootstrap/#/modals – Max Koretskyi Nov 22 '17 at 08:01
  • If `@ContentChild()` doesn't work, there probably isn't anything that will. What you you trying to accomplish? – Günter Zöchbauer Nov 22 '17 at 08:03
  • I'm not the one asking the question :) The problem is that bootstrap creates embedded view outside of the component with template, so `@ViewChild` won't work. If the embedded view using the template was created as a child of the component with template, `@ViewChild` would work – Max Koretskyi Nov 22 '17 at 08:22
  • Sorry, didn't check :D This is what `@ContentChild()` is for. It allows to query for descendants, projected or not, but the querying component has to be an ancestor. – Günter Zöchbauer Nov 22 '17 at 08:24
  • I need the input's `nativeElement` in `change` event – Veto Nov 22 '17 at 08:42
  • You can use `(change)="fileChange(newimg)"` or `fileChange(event) { event.target... ;}` with your code (`fileChange($event)`) – Günter Zöchbauer Nov 22 '17 at 08:43
  • `(change)="fileChange(newimg)"` this only works on input on another button `newimg` is undefined. – Veto Nov 22 '17 at 09:23
  • There is no mention of a button in your question. – Günter Zöchbauer Nov 22 '17 at 09:24
  • You could just add a directive to the input that injects a service, then inject the same service to the component that contains the button and use the service to communicate between both. – Günter Zöchbauer Nov 22 '17 at 09:24
  • @GünterZöchbauer, _it allows to query for descendants, projected or not_ - no, it's only used for projected nodes – Max Koretskyi Nov 22 '17 at 09:47
0

Use ContentChild instead of ViewChild, because your template reference is within a projected content (ngtemplate)

@ContentChild('newimg') img: ElementRef;
Venkatesh Muniyandi
  • 5,132
  • 2
  • 37
  • 40