1

当我的 Angular 应用程序第一次加载时,我需要对一些相当大的数据提出几个请求。然后在控制器和服务中使用此数据来确定如何显示页面。我收到各种 JavaScript 错误,因为控制器和服务在请求返回之前尝试访问这些数据。

我知道在 HTML 页面中,您可以绑定到这个异步数据,当请求返回时,Angular 会为您填充它。但是,基于这些数据,我的控制器和服务中发生了一些非常复杂的逻辑。所以,我想我有两个问题。

  1. 无论如何,有没有办法在控制器和服务中处理异步数据?
  2. 有没有办法防止 Angular 在数据返回之前尝试渲染页面?这基本上使数据请求同步,我可以接受。这只会在初始的完整 HTML 页面加载时发生。

我在 jsFiddle 上的尝试可以在这里找到:http: //jsfiddle.net/sES9T/

4

2 回答 2

3

基本流程应该是这样的:在你的控制器函数中,发出 $http 请求,并在 success() 回调中,根据需要设置你的 $scope 变量。您的流程与此不同吗?

此外,使用ng-show指令隐藏您的 DOM 元素,直到范围具有您需要的数据。

您的控制器将如下所示:

MyCtrl = ( $scope, $http ) ->
  promise = $http.get "/url"
  promise.success ( data ) ->
    $scope.foo = data

您的视图将如下所示:

div(ng-show="foo")
  p Here is my data, and some other stuff
  p {{ foo }}

编辑

我在这里修改了你的jsfiddle:

http://jsfiddle.net/sES9T/4/

它按预期工作,问题是您试图访问未定义变量的属性,这会引发错误。此外,在第三次测试中,变量命名错误,但命名正确时仍需要检查。

我建议使用 coffeescript,因为这些 if 语句可以使用存在 (?) 运算符变得更加简洁,如下所示:

myLargeData?.data

该代码将在尝试访问它的属性之前检查 myLargeData 是否已定义且非空,就像我在上面手动完成的那样。如果它是 undefined 或 null,它将返回 undefined,而不是导致错误。

于 2012-08-31T18:11:30.677 回答
0

我建议您使用路由器resolve来加载和处理所有必需的数据。只有当所有的解析都被真正解决时,控制器才会被执行。因此,在您的请求完成并处理数据之前,根本不会呈现视图。我确实相信这是一种更优雅和推荐的方法。

此外,您应该将所有数据加载和处理逻辑提取到一个单独的服务中,并将工作从解析中继到您的服务。您的服务应返回一个承诺对象,该对象将在所有处理完成后得到解决。

请参阅$routeProvider 的文档(“resolve”属性)。

于 2015-04-27T16:08:25.717 回答