如何手动重新渲染组件?

时间:2016-08-08 19:02:15

标签: angular angular2-routing

我是Angular2的新手,我已经习惯了Angular 1摘要周期,这意味着如果我更新视图的范围,我可以通过调用$scope.$digest()来手动触发摘要。但是,我不确定如何在Angular2中执行此操作,因为新框架没有旧版本具有的隐式数据绑定。

这是我的问题。我有一个路由,当一个带参数的网址被命中时加载一个组件:

// Router
export const AppRoutes : RouterConfig = [
    {
    path: 'my/:arg/view',
    component: MyComponent  
    }
]

然后我有这个组件:

// Component
export class MyComponent {
    constructor(private route : ActivatedRoute,
      private r : Router) {
    let id = parseInt(this.route.params['value'].id);
    console.log(id);
    // do stuff with id
    }

    reloadWithNewId(id:number) {
        this.r.navigateByUrl('my/' + id + '/view');
    }
}

让我说我导航到网址/my/1/view。它将调用构造函数并记录数字1。但是,如果我使用新ID reloadWithNewId调用reloadWithNewIf(2),则不会再次调用构造函数。如何手动重新加载组件?

4 个答案:

答案 0 :(得分:16)

不需要重新加载组件。只需更新模型,视图就会自动更新:

export class MyComponent {
    constructor(private route : ActivatedRoute,
      private r : Router) {}

    reloadWithNewId(id:number) {
        this.r.navigateByUrl('my/' + id + '/view');
    }

    ngOnInit() {
      this.sub = this.route.params.subscribe(params => {
         this.paramsChanged(params['id']);
       });
    }

    paramsChanged(id) {
      console.log(id);
      // do stuff with id

    }
}

答案 1 :(得分:13)

您可以通过导航到其他网址,然后返回到您想要的网址来强制angular2重新初始化组件。

以下是使用路由器类方法(参考:https://angular.io/docs/ts/latest/api/router/index/Router-class.html

的简单解决方法

组件构造函数:

constructor(private router: Router) {}

在模板(示例)中:

(click)="onTabChange(id)"

然后在组件类中:

onTabChange() {
  if (this.router.navigated === false) {
    // Case when route was not used yet
    this.router.navigateByUrl(`/module/${id}`);
  } else {
    // Case when route was used once or more
    this.router.navigateByUrl(`/index`).then(
      () => {
        this.router.navigateByUrl(`/module/${id}`);
      });
  }
}

答案 2 :(得分:3)

当您刚刚更新params时,不会再次调用构造函数。因为Component类已经实例化了,

如果要检测更改,可以订阅如下所示的参数更改

public Text text;
IEnumerator StartGPS()
{
    text.text = "Starting";
    //Pass true to use mocked Location. Pass false or don't pass anything to use real location
    LocationServiceExt locationServiceExt = new LocationServiceExt(true);

    LocationInfoExt locInfo = new LocationInfoExt();
    locInfo.latitude = 59.000f;
    locInfo.longitude = 18.000f;
    locInfo.altitude = -3.0f; //0.0f;
    locInfo.horizontalAccuracy = 5.0f;
    locInfo.verticalAccuracy = 5.0f;
    locationServiceExt.lastData = locInfo;

    // First, check if user has location service enabled
    if (!locationServiceExt.isEnabledByUser)
    {
        text.text = "Not Enabled";
        yield break;
    }
    else
    {
        text.text = "Enabled!";
    }

    // Start service before querying location
    locationServiceExt.Start();


    // Wait until service initializes
    int maxWait = 20;
    while (locationServiceExt.status == LocationServiceStatusExt.Initializing && maxWait > 0)
    {
        text.text = "Timer: " + maxWait;
        yield return new WaitForSeconds(1);
        maxWait--;
    }

    // Service didn't initialize in 20 seconds
    if (maxWait < 1)
    {
        print("Timed out");
        text.text = "Timed out";
        yield break;
    }

    // Connection has failed
    if (locationServiceExt.status == LocationServiceStatusExt.Failed)
    {
        print("Unable to determine device location");
        text.text = "Unable to determine device location";
        yield break;
    }
    else
    {
        // Access granted and location value could be retrieved
        string location = "Location: " + locationServiceExt.lastData.latitude + " "
            + locationServiceExt.lastData.longitude + " " + locationServiceExt.lastData.altitude
            + " " + locationServiceExt.lastData.horizontalAccuracy + " " + locationServiceExt.lastData.timestamp;
        Debug.Log(location);
        text.text = location;
    }

    // Stop service if there is no need to query location updates continuously
    locationServiceExt.Stop();
}

希望这会有所帮助!!

答案 3 :(得分:0)

我认为$(document).on("mousemove", function() { let mW = ((((event.pageX)*100)/vW).toFixed(3))-50; $("#red").css('transform', 'translateX(' +(-mW/2)+ '%)'); }); 是完成这项工作的合适工具:

HTML

changeDetectorRef

TS

<my-component *ngIf="!reloading"
              (loadNext)="onLoadNext()">
</my-component>

为什么要这样做,而不是像Günther提供的答案那样“更新模型并更新视图本身”?这样,您可以确保组件被重新初始化,并且之前没有剩余任何值。这就是为什么我觉得这样做更干净。

示例:https://stackblitz.com/edit/commatrainer-v1