Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

angular

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

like image 219
Milad Avatar asked Mar 19 '17 07:03

Milad


People also ask

Can a component have multiple templates?

Note Although it's possible for a component to render multiple templates, we recommend using an if:true|false directive to render nested templates conditionally instead. Create multiple HTML files in the component bundle.

What is difference between component and template?

Components meaning a piece of data that can be used in multiple places and can be rendered anywhere on the page. Essentially a free way of designing a web page without needing a developer's intervention. Page Templates meaning a much more rigid design of the pages that will prevent possible design complications.

How do you select an element with in a component template?

Add a template reference variable to the component HTML element. Import @ViewChild decorator from @angular/core in component ts file. Use ViewChild decorator to access template reference variable inside the component.


2 Answers

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.

like image 105
Negin Avatar answered Nov 15 '22 15:11

Negin


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

like image 25
eddyP23 Avatar answered Nov 15 '22 17:11

eddyP23