【问题标题】:How to reload the current Angular 2 Component如何重新加载当前的 Angular 2 组件
【发布时间】:2017-03-19 07:56:33
【问题描述】:

如何在 Angular 2 中重新加载相同的组件?

下面是我的代码:

import { Component, OnInit, ElementRef, Renderer } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { productModel } from '../_models/index';
import { categoryListService } from '../_services/index';

@Component({
  selector: 'app-product',
  templateUrl: 'product.component.html',
  styleUrls: ['product.component.css']
})
export class productComponent implements OnInit {
  uidproduct: productModel;
  param: number;
  constructor(
    private elementRef: ElementRef,
    private route: ActivatedRoute,
    private router: Router,
    private categoryListService: categoryListService) { }

  ngOnInit() {
    this.route.params.subscribe(product => {
      console.log('logging sub product obj', product);
    });
    this.uidproduct = JSON.parse(sessionStorage.getItem('product'));
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.src = "http://this/external/script/needs/to/be/loaded/each/time.js";
    this.elementRef.nativeElement.appendChild(s);
  }
  nextproduct(){ 
    let i = this.uidproduct.order;
    this.categoryListService.findNextproduct(this.uidproduct);
    this.param = ++i;
    this.router.navigate([`/product/${this.param}`]);
  }
}

nextproduct() 绑定到模板中的点击事件。

uidproduct 是一个 JSON 对象,它具有许多属性,我正在使用 {{uidproduct.classname}} 更新 DOM

我在这样的模板中使用它:

<div id="selected-product" class="{{uidproduct.classname}}">

当我单击&lt;button (click)="nextproduct()"&gt; 时,它将更改 DOM 中的类属性,但我需要重新加载组件才能使外部脚本生效。

【问题讨论】:

  • 我不认为组件重新加载选项会很好,我需要重新加载组件以使外部脚本生效。?
  • 外部脚本针对特定的 DOM 元素类属性并将特定产品呈现给 DOM。干杯!
  • 什么外部脚本?
  • @Dave 你不能从模板加载外部脚本(这将是安全威胁),我建议你通过this question
  • @PankajParkar 我现在已经从模板中删除了外部脚本,但是关于如何重新加载组件的任何更新都会很棒!

标签: javascript angular typescript angular-components


【解决方案1】:

您可以使用*ngIf 重新渲染模板的内容:

@Component({
  selector: '...',
  template: `
<ng-container *ngIf="!rerender">
 template content here
</ng-container>`
})
export class MyComponent {
  rerender = false;
  constructor(private cdRef:ChangeDetectorRef){}
  doRerender() {
    this.rerender = true;
    this.cdRef.detectChanges();
    this.rerender = false;
  }
}

【讨论】:

  • 很棒的技巧,像这样,我搜索了很多东西,尝试了很多合法的步骤,但都没有成功。在我的语言中很好的“JUGAD”
【解决方案2】:

我不明白您为什么需要重新加载组件。如果您绑定到uidproduct 的各个字段,那么重新加载应该会刷新组件中显示的值。所以重新加载组件只会增加开销。

如果这里没有提到你认为仍然需要这样做的绝妙原因,那么你应该这样做:

  1. 导航到另一个(可能为空白)组件。
  2. 直接返回。

问题是您需要等待第一个导航完成才能进行第二个导航。

在您的组件中,导入 NavigationEnd:

import { Router, NavigationEnd } from '@angular/router';

然后在你的构造函数中订阅它:

constructor(private thingService: ThisThingService, private router: Router) { 
   router.events.subscribe(event => {
    if (event instanceof NavigationEnd) {
      if (event.url === '/blank') {
        this.router.navigate(['product']); 
      }
    }
  });

请注意,我等待 NavigationEnd 发生,然后检查我是否正在路由到我的空白组件。如果它是空白组件的路径,我会导航回产品。如果您确实需要传递该 ID,只需将其存储在您的对象中并在此处添加即可。

不要路由到nextproduct() 中的产品页面,而是导航到blank。

this.router.navigate(['blank']);

这应该可以很好地重新加载您的组件。

为了简单起见,我故意留下的问题是构造函数中的subscribe 调用将在每次重新加载时执行。因此,作为对读者的练习,将其从构造函数中取出并为其创建一个不错的服务,或者将其移至应用组件的构造函数,或者移至路由模块或任何对您有意义的地方。

【讨论】:

  • 感谢它的工作,虽然逻辑不直。 @Günter Zöchbauer 回答不会更新我的服务,但它会更新我组件中的所有数据:)
猜你喜欢
  • 1970-01-01
  • 2017-04-20
  • 2018-02-05
  • 2018-03-20
  • 1970-01-01
  • 2017-01-16
  • 2018-08-13
  • 1970-01-01
  • 2019-09-24
相关资源
最近更新 更多