Yazan Mehrez
Yazan Mehrez

Reputation: 1204

How to reload component without affecting on others Angular +2

I have three components in one page, how can I reload this component onSubmit or after calling specific function. Suppose you have ckeditor component and you put text,image and videos, I want to reload the component after submit so that I can write a new subject.

Upvotes: 3

Views: 894

Answers (1)

smnbbrv
smnbbrv

Reputation: 24561

In my opinion this is not silly to say something.val('') because reloading the component means first of all reloading all its dependencies e.g. remote config etc. What I find silly is to reload the whole component when the only thing that is changed is a value of some input.

I am totally against reloading the component. However if you know what you are doing and it pays off, why not.

So, for the learning purposes: there are some ways to reload the component. Regardless of the way the only place where you can reload the component is the component's parent. So, you would need to emit some event from the component to the parent in order to trigger the reloading (I skip this part because it is obvious)

So, let's do the magic and wrap it inside a custom structural directive

@Directive({
  selector: '[showOrReloadOn]'
})
export class ShowOrReloadOnDirective implements OnChanges {

  @Input('showOrReloadOn')
  private reload: BehaviorSubject<boolean>;

  private subscription: Subscription;

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
  ) { }

  ngOnInit() {
    this.subscription = this.reload.subscribe(show => {
      this.viewContainer.clear();

      if (show) {
        this.viewContainer.createEmbeddedView(this.templateRef);
      }
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

}

Pretty much simple: you pass a subject and control how your component gets rendered.

This is a test component:

@Component({
  selector: 'my-reloaded-component',
  template: `component that is loaded {{loadedCount}} times`,
})
export class ReloadedComponent {

  static loadedCount = 0;

  constructor() {
    // here we increase the static counter 
    // which is component-instance-independent
    // meanwhile constructor is triggered only once 
    // that's why we are sure the component gets rerendered
    this.loadedCount = ++ReloadedComponent.loadedCount;
  }

}

And here is how finally we can show / rerender / hide the component from the parent component

@Component({
  selector: 'my-app',
  template: `
    <div>
      <button (click)="reload(true)">Show / Reload</button>
      <button (click)="reload(false)">Hide</button>
    </div>

    <my-reloaded-component *showOrReloadOn="reloader"></my-reloaded-component>
  `,
})
export class App {

  // this is our communication point
  // here we push true to show and false to hide the element
  // just to cover *ngIf functionality by the way to avoid problems
  // we also pass true as initial value in order to show the component directly
  reloader = new BehaviorSubject<boolean>(true);

  reload(show: boolean) {
    // trigger reload if true or hiding if false
    this.reloader.next(show);
  }

}

Plunkr: https://plnkr.co/edit/VOPpEtGJg3EnUMpQd0XB?p=preview

Upvotes: 2

Related Questions