如何在不影响其他组件的情况下重新加载 Angular +2 组件

3

我在一个页面上有三个组件,当我提交表单或调用特定函数后,如何重新加载该组件。假设您有 ckeditor 组件并放置文本、图像和视频,我想在提交后重新加载该组件,以便我可以编写新主题。


可能是XY问题,请告诉我们为什么要重新加载一个组件? - Harry Ninh
@HarryNinh 我有一个组件,我希望在提交后它变为空的。我编写了一个函数来将组件从(文本、图像、视频等)设置为空,但我认为使用 something.val('') 而不是重新加载组件是愚蠢的。通过重新加载组件,您可以避免 JavaScript 冲突或意外发生的情况。 - Yazan Mehrez
重新加载组件不会重置您的字段,除非您在重置函数中执行它;) 因此,请使用ngForm和双向绑定或在每个字段上使用viewchild访问DOM值#textInput... - andrea06590
1个回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接