如何重新加载组件而不影响其他Angular +2

时间:2018-01-14 09:55:32

标签: angular

我在一个页面中有三个组件,如何在子提交或调用特定功能后重新加载此组件。假设您有ckeditor组件,并且您放置了文本,图像和视频,我想在提交后重新加载组件,以便我可以编写新主题。

1 个答案:

答案 0 :(得分:2)

在我看来,说something.val('')并不愚蠢,因为重新加载组件意味着首先重新加载所有依赖项,例如远程配置等。我觉得愚蠢的是当唯一改变的东西是某个输入的值时重新加载整个组件。

我完全反对重新加载组件。但是,如果你知道自己在做什么并且有所回报,那么为什么不呢。

因此,出于学习目的:,有一些方法可以重新加载组件。无论何种方式,您可以重新加载组件的唯一方法是组件的父级。所以,你需要从组件向父级发出一些事件才能触发重新加载(我跳过这部分是因为很明显)

所以,让我们做一些魔术并将其包装在自定义结构指令

@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();
  }

}

非常简单:您传递主题并控制组件的呈现方式。

这是一个测试组件:

@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;
  }

}

以下是我们最终如何显示/重新隐藏/隐藏父组件

中的组件
@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