I am looking at the *ngIf
's source code :
@Input()
set ngIf(condition: any) {
if (condition && !this._hasView) {
this._hasView = true;
this._viewContainer.createEmbeddedView(this._template);
} else if (!condition && this._hasView) {
this._hasView = false;
this._viewContainer.clear();
}
}
Can I have a component that does like below?
@Component({})
class MyComponent{
constructor (
public _template : TemplateRef,
public _viewContainer : ViewContainerRef) {
}
onSomeButtonClick(condition){
if(condition){
removeMyView();
}else{
putTheViewBackIfItsRemoved();
}
}
}
Trying to use ngIf
's logic inside the component doesn't work, which I think it's because the viewContainerRef for the component is empty
EDIT :
Just to mention that I'm not looking to hide the view , I just want to remove it from the DOM.
In other words, can we something like ngIf
of host elements ?
I know you can't put a directive on host
, that's why I thought maybe with ViewContainer
and TemplateRef
you could achieve the same.
The other thing is, having worked with Angular and creating dynamic components, I now the only way is to use ViewContainerRef
to create a new component in DOM; my important question is, does Angular itself create components the same way ?
If yes, can't we somehow access that container which holds the components ?
For those who've just started learning Angular and want to be helpful here ( thanks for that ) , I should say that I sincerely know how to use ngIf
inside my template :
I now what a ngIf
is and what it does :
but :
<div *ngIf="condition"></div>
is not what I mean, simply because this will potentially remove what is inside my template, and I have to wrap every thing inside that div to make it work , which is not what I want.
I want to clear the template all together with ngIf
ing the inside.
UPDATE:
To give some clarification :
In other words , it's like having a ngIf
on host :
@Component({
host:{
'*ngIf':'shouldBeRemoved'
}
})
class MyComponent{
I know you can't put ngIf on host because its directive and host only compiles static values , that's why I'm asking if there is a way to handle it with viewContainerRef
or something .
Please do know get confused by putting ngIf
inside the template , that's not what I want.
Thanks for your patience again.
There is no official way of removing a template from inside a component and for me it makes sense.
If you remove your template, who is gonna take care of putting it back.
This works in ngIf
because ngIf
first creates a template
behind the scene and then embeds the element inside it, so it has a reference to the embedded element, therefore it can delete it or put it back.
Here is what you are looking for:
@Component({
selector: 'your-selector',
template: '<template [ngIf]="showView"> Here is my component template </template> ',
})
class MyComponent{
showView: boolean = true;
onSomeButtonClick(condition){
if (condition) {
this.showView = false;
} else {
this.showView = true;
}
}
}
Now, just add some button with an onClick callback to call onSomeButtonClick
with some param and you are done
I can only answer base on my limited understanding of how angular2 and typescript work.
No.
At typescript level, template and the class look like separate part. However the template is actually part of the class declaration.
Once a component class is initiated, all those template variable binding, directive, etc, become bits and pieces inside the component object.
Changing, including removing(what the question is asking for), the template basically means re-writing the class, will need re-transcripting, then recompile/reinit by the angular2 engine.
In a programing point of view this is possible, especially with javascript objects, which can have method deleting all siblings and reinitiate everything. However, I don't see an angular2 way for a component to reboot itself.
Currently the closest technique I know of is dynamic component, of which the parent component can create and destroy. And it is mentioned in the question.
(rebooting a component is almost the same as dynamic component, difference is initiated internally or externally.)