Angular.js: 支持异步 module.run()

创建于 2013-09-13  ·  62评论  ·  资料来源: angular/angular.js

我们想在模块运行块中发出一些 $http 调用,理想情况下,运行应该在 $http 和处理完成后才完成,然后 dom 编译发生。

Lots of comments won't fix feature

最有用的评论

jfcfxekzl5m
简单的功能,但太难实现。 😕

所有62条评论

这不是那么容易,但应该调查一下。

Jasmine 这样做的方法是通过设置一个标志,让函数运行并等待回调,直到标志设置为true ,或者直到触发超时。

基本上是这样的:

var flag = false;
$http(...).success(flag = true);
$timeout(function () {
    flag = true;
    // Or add some error handling stuff here
}, 5000);
while (!flag) {};

它不漂亮,但应该可以完成这项工作。 上面的代码没有经过测试,所以你可能需要稍微修改一下。 这里已经很晚了。 希望有什么东西可以让你度过难关,直到出现更漂亮的东西。

+1

不过,这确实导致无法使用角度指令绘制精美的加载屏幕......

+1

$routeProviderresolve不能解决这个问题吗? 可能我没看懂问题...

这更多是为了异步模块初始化支持。 话虽如此,我在当前的项目中不再需要这个。

@shahata $routeprovider执行此操作,但并非所有承诺给予run的用例都使用路由。 在我的用例中,它用于包装指令且与路由无关的模块。

+1

检查 run 函数是否返回一个承诺,然后只在它解决时才继续。 因为runBlocks是一个函数数组,所以应该不难

+1

+1 令人尴尬的是这被忽略了

知道这什么时候降落吗? 不得不移动初始化内容以在路由器中解析非常令人沮丧,主要是因为有时初始化代码与 url 无关(也就是必须针对用户到达您的 SPA 的任何类型的 URL 进行初始化)

我认为 angular 以后不会有任何改进。 它们都被添加到 angular 2.0

半途而废的run方法将保持同步多久? config不支持异步调用是可以理解的,因为您没有任何提供$http调用的提供程序,但run 。 看看缺少此功能(从一开始就应该存在)导致的黑客攻击类型
https://github.com/philippd/angular-deferred-bootstrap/blob/master/src/deferred-bootstrap.js

这让人很难堪

+1

@btford正在研究如何通过新路由器而不是内部运行块来支持围绕此的用例。

+1

+1

+1

+1

我们遇到的主要问题是$q是在运行 runBlock 时正在加载的模块中创建的。 这意味着我们需要以某种方式提取“某些”服务(或者可能是模块)并首先创建它们,然后在 $q 之后进行第二次加载以加载其余模块(以及服务、运行块等)被创建。

@lgalfaso - 也许您可以在本周晚些时候(或下周)作为$injector工作的一部分对此进行更多研究?

我知道这只是一种解决方法,但我通常通过使用 angular ui 路由器并结合解析根抽象状态来解决具有一些异步引导逻辑的问题。 根抽象状态必须始终首先解析,因此它是加载设置、显示加载动画等的好地方。

这真的很棒。
:+1:
等待这个修复。 希望它会在 1.4

+1

我有另一个用例:我需要在启动时使用 $http 调用来初始化我的模拟端点(以缓存一些数据)...

+1

+1

也偶然发现了这个......

@petebacondarwin我认为可以继续加载所有其他模块,但推迟启动初始导航。

或者, $routeProvider 可以提供一个可配置的函数参数,该参数应该延迟渲染初始路由。

+1

+1

这是一个可能的解决方法: http :
这个想法是 Angular 实际上让您能够从一组模块创建自己的注入器。 在这种情况下,我推迟编译$rootElement直到一堆承诺( resolves )得到解决。 这是一个 POC,并且还需要许多其他花里胡哨的东西来使此产品做好准备。 除了其他任何事情外,您还需要捕获解析中的错误,而不仅仅是吞下它们。

+1

这主要是给想要试一试的人的指南; 目前,引导程序执行以下操作:

  • 健全性检查
  • $rootElement创建生产
  • 创建注入器
  • 编译并链接$rootElement

最重要的是,在创建注入器时,步骤如下:

  • 遍历依赖模块树和

    • 模块初始化,将注册模块常量、值、提供者和其他东西

    • 运行配置函数

    • 收集run函数供以后使用

  • 运行所有run函数

有几个关键点:

  • 在编译$rootElement之前执行所有run
  • 在注入器创建过程中没有摘要周期,第一个摘要周期是在$rootElement的初始编译期间
  • $q在摘要循环中解析 _only_

这是:

  • 如果有一个模块有一个run函数返回一个promise,并且这个promise 需要在app 启动之前解析,那么在初始编译之前会有digest 循环(这可能会破坏现有的app)
  • 配置块不能返回承诺,因为config函数是通过提供者而不是实例注入的

无论解决方案,都需要处理这些情况

+1
任何新闻?
我只想在应用真正启动之前加载一些配置设置。

+1

当我的所有工厂都启动后和编译之前,我会在引导后加载一些异步数据。

@dagingaa :我想我会选择您的解决方案作为解决方法! 谢谢

  • 1

更新到@dagingaa :for 循环冻结了我的浏览器,不好...

https://jsfiddle.net/tuxmachine/t4d63vnw/

这就是我为 OAuth 令牌实现解决它的方法,这需要在初始化应用程序的其余部分之前解析初始 ajax 调用。

如果您有多个异步运行块,则不起作用

+1

+1

+1

开issue已经两年了,还是没有好的解决方案

@vladmiller有解决方案,但也许您觉得它们不好:

将重要的应用程序工作放在.run块中会使对代码进行单元测试变得困难。 所以这不是我们想要鼓励的。 将其移至 Ice Box 作为我们不太可能实施的内容。

@petebacondarwin我不同意你的观点; 每个人都希望 angluar 简单直观,相反,您必须在不同的地方实现自己的异步引导模块或引导模块。 在我看来,这使得 angular 变得更加复杂。

当您说.run中的异步代码会使测试更加困难时,您能解释一下您的意思吗?

为我之前的粗鲁评论道歉。
谢谢

@petebacondarwin我看不出它是如何使测试变得困难的。 如果您将初始化代码放在服务中,您只需观察/模拟/比较您将从 http 后端模拟中得到的结果,无论它是否在.run块中执行。 由于缺乏异步运行的变通方法,代码存在于 angular 之外,这使得测试几乎不可能

最近怎么样?

另一种方法: http :

@petebacondarwin解决方案对我

由于存在变通方法并且支持异步运行块会增加引导程序的复杂性,我认为我们不会实现此功能。

jfcfxekzl5m
简单的功能,但太难实现。 😕

+1 此功能

+1

+1

@petebacondarwin解决方案效果很好。

+1。 :(

+1

+1

+1

+1

我们不会这样做。

+100,所有的变通方法都很糟糕。

@Eduardo-Julio - 我们不会实现此功能,因为它会使 AngularJS 应用程序的引导程序变得更加复杂。 添加更多的+将无济于事。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

jpsimons picture jpsimons  ·  3评论

jtorbicki picture jtorbicki  ·  3评论

nosideeffects picture nosideeffects  ·  3评论

butchpeters picture butchpeters  ·  3评论

ceymard picture ceymard  ·  3评论