Can a component remove it's own template and put it back conditionally?


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 bellow :

@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 it's empty

EDIT :

Just to mention that I'm not looking for hiding the view , want to remove it from DOM.

In another 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 , but my important question is, does Angular itself create components the same way ?

If yes, can't we somehow access to 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 ngIfing 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 it's 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.

- - Source

Answers

answered 2 year ago eddyP23 #1

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

answered 2 year ago Negin #2

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.

answered 2 year ago John Siu #3

I can only answer base on my limited understanding of how angular2 and typescript work.

Short Answer

No.

Long Answer

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.)

answered 1 week ago Idan Steinberg #4

I suggest that the component that you want to it to remove itself, will be unmounted by its host with a boolean that's binded to ngIf. in order for the component, to practically remove itself, the boolean should have the value of a state in redux, and that state will be set only by the component that you want it to be removed by itself :)

comments powered by Disqus