Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度4-如何确保在航行离开前完成Ngondestry_Javascript_Angular_Rxjs_Settimeout - Fatal编程技术网

Javascript 角度4-如何确保在航行离开前完成Ngondestry

Javascript 角度4-如何确保在航行离开前完成Ngondestry,javascript,angular,rxjs,settimeout,Javascript,Angular,Rxjs,Settimeout,我有一个物品清单。用户可以单击其中一个,然后加载子组件以编辑该组件 我遇到的问题是,当用户返回列表组件时,子组件必须在Ngondestory方法中进行一些清理,这需要调用服务器对对象进行最后的“修补”。有时这种处理可能有点慢 当然,发生的情况是用户返回列表,并且在ngondestory中的数据库事务完成之前,api调用就完成了,因此用户会看到过时的数据 ngOnDestroy(){ this.destroy$.next(); this.template.template_it

我有一个物品清单。用户可以单击其中一个,然后加载子组件以编辑该组件

我遇到的问题是,当用户返回列表组件时,子组件必须在Ngondestory方法中进行一些清理,这需要调用服务器对对象进行最后的“修补”。有时这种处理可能有点慢

当然,发生的情况是用户返回列表,并且在
ngondestory
中的数据库事务完成之前,api调用就完成了,因此用户会看到过时的数据

  ngOnDestroy(){
    this.destroy$.next();
    this.template.template_items.forEach((item, index) => {
      // mark uncompleted items for deletion
      if (!item.is_completed) {
        this.template.template_items[index]['_destroy'] = true;
      };
    });
    // NOTE 
    // We don't care about result, this is a 'silent' save to remove empty items,
    // but also to ensure the final sorted order is saved to the server
    this._templateService.patchTemplate(this.template).subscribe();
    this._templateService.selectedTemplate = null;
  } 
我知道不建议进行同步调用,因为它会阻塞UI/整个浏览器,这并不好

我确信有多种方法可以解决这个问题,但我真的不知道哪种方法是最好的(特别是因为Angular不支持同步请求,所以我不得不回到标准ajax来实现这一点)

我确实想到的一个想法是,Ngondestory可以向API传递一个“标记”,然后它可以将该对象标记为“正在处理”。当列表组件进行调用时,它可以检查每个对象是否有该标记,并为处于该状态的任何对象显示一个“刷新过时数据”按钮(99%的时间都是单个项目,是用户编辑的最新项目)。这似乎是一个有点垃圾的解决方法,与将异步调用更改为同步调用相比,需要大量额外的代码

其他人肯定也遇到过类似的问题,但我似乎找不到任何明确的例子,除了

编辑

请注意,此子组件上已经有一个CanDeactive保护。它要求用户确认(即放弃更改)。因此,如果他们单击确认,则会执行Ngondestory中的清理代码。但请注意,这不是一个典型的角度形式,用户实际上是“放弃”更改。基本上,在离开此页面之前,服务器必须对最后一组数据进行一些处理。因此,理想情况下,我不希望用户在Ngondestory完成之前离开—我如何强制它等待api调用完成

我的CanDeactive guard的实现与Hero应用程序中的实现几乎相同,它连接到一个通用对话框服务,提示用户是否希望留在页面上或离开。这是:

  canDeactivate(): Observable<boolean> | boolean {
    console.log('deactivating');
    if (this.template.template_items.filter((obj) => { return !obj.is_completed}).length < 2)
      return true;

    // Otherwise ask the user with the dialog service and return its
    // observable which resolves to true or false when the user decides
    return this._dialogService.confirm('You have some empty items. Is it OK if I delete them?');
  }


正如您所说,有很多方法,它们取决于您的整个应用程序、数据流和用户体验流的其他细节设置,但您可能想看看
CanDeactivate
guard方法,该方法确保用户在您的
Observable | Promise
解析为
true
之前不能离开路线

所以,这是一种异步等待的方式,直到您的服务确认服务器上的内容发生更改

[更新]

这取决于您的用户确认实现,但大致如下

waitForServiceToConfirmWhatever(): Observable<boolean> {
    return yourService.call(); //this should return Observable<boolean> with true emitted when your server work is done
  }

canDeactivate(): Observable<boolean> {

    if(confirm('do you want to leave?') == true)   
      return this.waitForServiceToConfirmWhatever();
    else
      Observable.of(false)
  }
WaitForService配置文件():可观察{
return yourService.call();//当服务器工作完成时,它应该返回Observable并发出true
}
canDeactivate():可观察{
if(confirm('您想离开吗?')==true)
返回此.waitForServiceToConfigWhather();
其他的
可观察的(假)
}

我能想到的一个“解决办法”是将您的列表放在客户端。您可以将列表作为JS数组或对象,并基于此显示UI。在详细信息屏幕中编辑后,在更新其他相关数据时,在服务调用的
ngondestory
上清除项目上有一个过时的标志。

查看CanDeactivate或guards,请参阅示例。谢谢,这不是解决方案。我将更新问题以解释原因。@rmcsharry这是一个解决方案。您在
CanDeactivate
中的用户确认不是解决方案。如果这是解决方案,为什么不起作用?我已经有了一个CanDeactivate守卫。当防护装置激活时,会提示用户。当他们“继续”走的时候,Ngondestory被叫来做清理工作。谢谢,但是路线已经有了一个坦率的守卫。它会提示用户是/否,如果用户回答是,则会触发正在进行清理的Ngondestory代码。在那之前我不能做清理工作。因此出现了一个catch-22。我要做的是像组件中的常规单击处理程序一样有yes/no提示。然后,如果用户单击“是”,我将转到路由器。导航['whereverYourListIs']。然后,使用我在回答中描述的
CanDeactivate
。我看不出您有什么理由在
CanDeactivate
guard中处理yes/no。这属于组件本身,即使是在组件
ngondestory
中也不属于组件本身,因为它只是一个常规的用户操作,就像其他任何与组件生命周期无关的操作一样,用户简单的“否”不应该做任何事情。希望这是有意义的。我不处理是/否。用户可以导航到任何地方,但我不知道(或关心)他们下一步想去哪里。无论他们选择去哪里,阳光都会燃烧。它检测是否还有工作要做(即,对象未处于“最终”状态),警卫抛出提示(基本上,你确定要离开并扔掉其他东西吗?)。单击“否”不会执行任何操作,正如CanDeactive的本意一样-用户将停留在页面上。如果他们单击“是”,警卫将允许他们继续,卸载组件并自动调用Ngondestory。我认为答案可能在于您的陈述“用户不能离开路由,直到您的可观察承诺被解析为真”——那么我如何更改警卫以确保在离开之前解决对API的调用?例如,我可以将api调用链接到dialog服务调用吗?好的,在用户单击“是”之后,有什么阻止您向您的服务发出额外的请求,并等待其
可观察的
解析为
true
,然后允许用户离开(
CanDeactivate
返回
true
),这是一个错误
    return this._dialogService.confirm('You have some empty items.
        Is it OK if I delete them?').subscribe(result => {
      ...if yes then call my api and return true...
      ...if no return false...
      });
waitForServiceToConfirmWhatever(): Observable<boolean> {
    return yourService.call(); //this should return Observable<boolean> with true emitted when your server work is done
  }

canDeactivate(): Observable<boolean> {

    if(confirm('do you want to leave?') == true)   
      return this.waitForServiceToConfirmWhatever();
    else
      Observable.of(false)
  }