Angular4 - 如何确保 ngOnDestroy 在离开之前完成

2024-06-25

我有一个对象列表。用户可以单击其中一个,然后加载一个子组件来编辑该组件。

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

当然,发生的情况是用户返回到列表中,并且该 api 调用在数据库事务从ngOnDestroy完成,因此用户看到陈旧的数据。

  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 来做到这一点)。

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

其他人一定也遇到过类似的问题,但我似乎找不到任何明确的例子,除了这个同步的 https://stackoverflow.com/questions/38999842/angular-2-execute-code-when-closing-window.

EDIT

请注意,该子组件上已经有一个 CanDeactive 防护。它要求用户确认(即放弃更改)。因此,如果他们点击确认,那么 ngOnDestroy 中的清理代码就会被执行。但请注意,这不是典型的角度形式,用户真正“放弃”更改。本质上,在离开此页面之前,服务器必须对最终数据集进行一些处理。因此,理想情况下,我不希望用户在 ngOnDestroy 完成之前离开 - 如何强制它等待 api 调用完成?

我的 CanDeactive 防护的实现几乎与官方文档 https://angular.io/guide/router#candeactivate-handling-unsaved-changes对于 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?');
  }

不过,文档并没有明确说明我的情况 - 即使我将清理代码从 ngOnDestroy 移至对话框的“YES”方法处理程序,它仍然必须调用 api,因此 YES 处理程序仍会在 API 之前完成做了,我又遇到了同样的问题。

UPDATE

阅读所有评论后,我猜测解决方案是这样的。将守卫从:

    return this._dialogService.confirm('You have some empty items. 
        Is it OK if I delete them?');

to

    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...
      });

正如你所说,有很多方法,它们取决于你的整个应用程序、数据流和用户体验流的设置方式的其他细节,但感觉你可能想看看CanDeactivate保护方法,确保用户不能离开路线,直到您Observable<boolean>|Promise<boolean>决心true.

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

[UPDATE]

这取决于您的用户确认实施,但沿着这些思路......

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)
  }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular4 - 如何确保 ngOnDestroy 在离开之前完成 的相关文章

  • JavaScript 中的负数到二进制字符串

    任何人都知道为什么javascriptNumber toString https developer mozilla org en US docs JavaScript Reference Global Objects Number toS
  • 使用 IE 11 和 AngularJS 的 2 路数据绑定问题

    我最近在使用 AngularJS 的 Web 应用程序上构建了一个功能 但在 IE 11 上遇到了一些问题 apply 将数据更改写入 DOM 由于某种原因 这种情况仅有时发生 而当我尝试调试问题时却从未发生 这使得它看起来像是一个计时问题
  • 如何捕获jquery中的任何点击事件[重复]

    这个问题在这里已经有答案了 我有一个按钮 当单击它时 会显示一个带有图像的 div 例如聊天的表情符号面板 如果我再次单击它 div 会隐藏 但我想要做的是 如果 div 已经显示 然后我单击页面的任何其他内容 我想隐藏它 我试过这个 my
  • $(document).ready 回调何时执行?

    假设我们附加一个 click http api jquery com click 锚点的处理程序 a 中的标签 document ready http api jquery com ready 打回来 该处理程序将取消默认操作 遵循href
  • 通过标记或JS强制下载

    假设我在 CDN 来自 Rackspace 的云文件 上有一个文件 以及一个包含该文件链接的静态 html 页面 有什么方法可以强制下载此文件 以防止它在浏览器中打开 例如 mp3 我们可以让我们的服务器读取该文件并将相应的标头设置为 he
  • ECMAScript 中定义的内部属性是什么?

    什么是内部属性 http es5 github com x8 6在 ECMAScript 中定义为 规格是什么意思 该规范使用各种内部属性来定义 对象值的语义 这些内部属性不是 ECMAScript 语言 它们是由本规范定义的 纯粹用于说明
  • 为什么 jQuery 对损坏标记的解释与浏览器不同?

    我之前已经回答过这个问题 https stackoverflow com a 19101905 1253312 但我并不完全理解why答案是正确的 答案的要点 p p function jqrender html a href http w
  • Javascript CORS 图像/画布操作

    我正在尝试从另一个已配置为允许 CORS 的域检索图像 并操纵像素 然后我想显示结果并能够操纵结果 我可以在我请求的图像上使用 getImageData 和 toDataURL 所以我知道服务器部分可以工作 但是 当我尝试将图像的 src
  • 将jQueryUI datepicker附加到div(显示位置错误)

    我在输入上使用 jQueryUI datepicker 默认情况下 jQueryUI 会附加 ui datepicker div to the body该文件的 有问题的输入位于屏幕上的 弹出 div 中 这意味着该 div 之外的任何点击
  • JQuery mouseover 函数多次触发

    我很长时间以来一直使用这种方法来为整个类 按钮等 设置事件 div bigButton mouseover function this style backgroundColor dfdfdf 然而 在进行一些测试时 我刚刚注意到 当将鼠标
  • 如何在传单地图上显示热图

    我想在我的传单地图上显示热图 我使用了 heatmap jshttps github com pa7 heatmap js https github com pa7 heatmap js但它最终只是显示 未捕获的类型错误 无法分配给只读属性
  • mat-table 自动调整列宽以适应更大的内容

    我有一个垫表 我想自动调整列宽 任何人都将与最长的列内容一样长
  • Lighthouse 多个 URL

    我需要对一个网站进行全面审核 但我想知道是否有任何方法可以让 Lighthouse 做到这一点 我知道他们不支持完整的站点审核或多个 URL 但我发现可以使用 bash 脚本来完成 因此 我将不胜感激对此案的任何帮助 或者您可能会推荐任何灯
  • 如何使用javascript将数据存储在xml文件中?

    我是 javascript 新手 并在我的项目中使用它 因为我需要读取 xml 文件 然后在操作后我想将更新后的值存储回 xml 文件中 我成功从 xml 文件获取值 但无法存储值返回到 xml 文件 这是我尝试过的代码
  • 汇总异常以保留模块

    我使用一个名为的汇总插件rollup plugin lit css转变 css文件转换成 javascript 模块 该插件非常简单 它本质上只是附加export default到文件 我的汇总配置使用preserveModules and
  • JavaScript 模板文字稍后替换变量(在知道值之前)

    是否可以在已知值之前以某种方式使用模板文字 JS 模板文字的每个演示都如下所示 var name John var s Hello name 但在现实世界中 模板是在我们知道变量值之前定义的 某处定义了模板 在页面加载时 var s Hel
  • RxJs / Typescript 抛出“类型 {} 上不存在属性 clientX”

    我想做一些非常简单的事情 只需在鼠标悬停时记录 event clientX 这是模块代码 import Observable Subject from rxjs import StarSky from starsky import cons
  • Angular2模板参考变量和动态更新

    我最初试图在 Angular2 中设置一个模板引用变量 这样我就可以反转表的排序顺序 而不必进行绑定 但当我单击复选框时 我没有得到界面的动态更新 我创建了一个简单的 plunker 以防应用程序中的其他内容可能会扰乱代码 并且我看不到正在
  • 如何从索引文件迭代多个导入的模块

    我有一个名为Polygons我在那里创建了一个index jsfile 以导出目录中的所有文件 它看起来像这样 export default as europe from europe export default as northAmer
  • 如何将国家/地区代码与电话号码分开?

    我的数据库中有很多电话号码 例如 1 123 456 7890 我要做的是将国家 地区拨号代码 在本例中为美国 加拿大的 1 与电话号码分开 我尝试创建所有国家 地区的 JSON 列表 并在加载页面时将电话号码和国家 地区代码分开 它工作正

随机推荐

  • 下面的 C 程序的输出是什么? [复制]

    这个问题在这里已经有答案了 char getString char str Will I be printed return str int main printf s getString getchar 输出不应该是 我会被打印吗 相反
  • RcppEigen 包“#pragma clang Diagnostic pop”警告

    我在尝试使用时遇到一些问题RcppEigen包裹 我使用了发布的示例here http gallery rcpp org articles eigen eigenvalues 该函数有效 但 R 生成了一系列类似的警告 示例如下 In fi
  • C++中return语句后可以执行代码吗? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我是一名java程序员 刚刚接触C
  • Ember.js 中按钮的绑定启用状态

    我刚刚开始接触 Ember js 但我遇到了一些我确信我不理解的东西 我有一个选定的对象控制器 它有一个 Ember Object 内容 即当前选择的模型 该模型有一个属性 isDirty 基本上我希望仅当对象脏且需要保存时才启用表单上的保
  • 是否可以在 UITabBarController 内显示 SFSafariViewController?

    我要加载SFSafariViewController位于选项卡内部 因此选项卡栏位于整个 Safari 视图的底部 这可能吗 我尝试了这个但没有运气 self tabBarController presentViewController s
  • jsp ${pageContext.request.contextPath} 未收到请求

    目前我有一个 jsp 项目 其中我的欢迎页面是一个 servlet
  • Django X-CSRFToken 已设置但仍然收到 403 禁止

    我开发了一个 Django 文件上传 API 它接收来自客户端的发布数据并将数据保存为文件 根据Django CSRF 手册 https docs djangoproject com en 1 8 ref csrf HTTP 请求标头应使用
  • HTTP 缓存的授权检查

    我有如下列出的 Web API 方法 用于REST服务 这是为了获取库存审核员的所有用户信息 只有授权的 Inventory Auditor 用户才能访问此资源 RoutePrefix api users public class User
  • 为 REST Spring HATEOAS 控制器定义资源组装器

    我正在尝试将 HATEOAS 链接添加到由 Spring REST 控制器提供服务的 JSON 资源 我发现我应该使用资源汇编器 如下所述https github com spring projects spring hateoas htt
  • 是否可以复制 Azure 网站?

    我想将现有的 共享 模式 开发 网站复制到另一个 测试 共享 模式网站 这可能吗 我知道可以使用 T SQL 命令通过 SQL Azure DB 来完成此操作 此刻我 1 创建新网站 2 跨 Dev Azure 网站的 FTP 来测试 Az
  • posix 和 linux 特定函数的 C++ 包装器 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 您知道有什么好的库将 posix 和 linux 函数和结构 例如套接字或文件描述符 包装到 C 类中
  • 在图像批次中随机打乱补丁

    我正在尝试创建一个transform打乱批次中每个图像的补丁 我的目标是以与其他转换相同的方式使用它torchvision trans transforms Compose transforms CenterCrop 224 transfo
  • 字符串常量之前的预期标识符

    有一个这样的程序 include
  • 当我所做的只是压缩提交时,为什么 git-rebase 会给我带来合并冲突?

    我们有一个包含 400 多个提交的 Git 存储库 其中前几十个提交需要大量的反复试验 我们希望通过将许多提交压缩为单个提交来清理这些提交 当然 git rebase 似乎是最佳选择 我的问题是它最终会产生合并冲突 而且这些冲突并不容易解决
  • 用模板替换 ng-include 节点?

    对角度有点陌生 是否有可能replace包含模板内容的 ng include 节点 例如 与 div div src div div 生成的html为 div div src div div
  • 使用finally代替catch

    我已经多次看到这种模式了 bool success false try DoSomething success true finally if success Rollback 我一直想知道 为什么这比使用 catch 进行回滚更好 try
  • 加载 ng2-table 数据表单 API

    我正在学习 Angular 2 我想使用 PHP 中的 API 数据填充 ng2 table 我有一个返回数据的服务 但我不知道如何使用服务的订阅数据填充数据变量 我正在调用服务方法 getLanguages 我的服务代码是 import
  • 表排序器,无法正确按日期排序

    如果存在空格 表排序器的行为是否会有所不同 我对 tablesorter 还很陌生 但有人要求我快速将其添加到客户网站 特别是允许他们按发布日期排序 据我所知 日期 例如 2012 年 5 月 14 日 被读取为文本 因此我需要添加一个解析
  • 错误:‘:’标记之前需要初始化程序

    我正在尝试编译一些 C 代码 可以在 Windows 上使用 Visual Studio 2012 进行编译 g 4 4 我有这段代码 const std string cnw restoreSession const std vector
  • Angular4 - 如何确保 ngOnDestroy 在离开之前完成

    我有一个对象列表 用户可以单击其中一个 然后加载一个子组件来编辑该组件 我遇到的问题是 当用户返回列表组件时 子组件必须在 ngOnDestroy 方法中进行一些清理 这需要调用服务器来对对象进行最终的 修补 有时此处理可能会有点慢 当然