确保数据在没有单独请求的情况下加载到视图中

Assure that the data is loaded in a view without an individual request

本文关键字:加载 情况下 视图 请求 数据 没有单 确保      更新时间:2023-09-26

我很确定一定有一个优雅的解决方案来解释这种角度的模式,我只是看不到它。

问题:

  • 所有数据在应用程序启动时批量加载一次。
  • 用户通过输入 URL 请求某个视图(如 /#/users/13
  • 问题:数据尚未加载

服务器

我的后端服务器一次从其所有表中返回所有可用数据(并不多)作为 JSON

{users: [...], groups: [...], stuff: [...], ...}

服务内容

我用update()方法将其包装在一个角度服务中,该方法将在成功时将响应的元素放在$rootScope中,因为这是整个应用程序正在处理的内容:

.success(function (data) {
    $rootScope.users = data.users;
    $rootScope.groups = data.groups;
    ...
}

应用启动后,将在主控制器中调用更新方法。

控制器/视图

当我为某个用户创建视图时,例如/users/:id,在应用程序内导航一切正常。目前为止,一切都好。

当我使用指向#/users/13之类的视图的深层链接启动应用程序时,数据尚未加载,因此控制器无法像往常一样链接数据,从而导致错误:

$scope.user = $scope.users[$routeParams.id];

想法

我必须解决这个问题的所有想法都以某种方式存在问题。

  • 对控制器中未定义的$scope.users做出反应可以避免错误,但是一旦数据存在,我将如何重新加载视图?
  • 为路由设置依赖于该服务结果承诺的resolve部分将在每次使用路由时重新加载,即使数据已加载(数据应仅在应用程序启动时加载)
  • 为每个数据部分设置服务并对每个结果使用承诺将从服务器多次获取数据
  • 为"数据已加载"设置显式标志并根据其状态更改内容对我来说似乎是完全错误的
  • 使用承诺通常会让我头疼,因为只有一大堆获取的数据,但我们想引用其中的单个元素

所以恐怕我只是错过了这种设置的"角度方式"(可能只是盲目)。

如果您有

应始终加载的数据,则可以将其加载到应用程序"app.run"中。这总是先于其他任何事情完成。它不会使您不必等待 http-requests,因为它仍然是异步的,但您可以使用它来确保数据始终从服务器加载(并且只加载一次,因为 app.run 只运行一次)。获取数据后,可以将其存储在服务或 rootScope 中,以便控制器和其他人可以使用它。

这负责确保加载数据的调用始终运行,并且只运行一次。第二部分是等待数据,为此我仍然会使用解析。

  1. 检查服务或根范围以查看数据是否已存在。
  2. 如果是这样,那就太好了。
  3. 如果没有,请使用手表等待它。
  4. 解决承诺后,显示视图。

通过将数据存储在服务中,我的意思是使用这样的东西:

app.factory('DataObject', [function(){
  return {};
}]);

服务是单例,因此使用此对象的任何内容都将共享相同的数据。因此,解析可以依赖于它并使用它来检查数据是否存在。您也可以将rootScope用于同样的事情,但是使用服务可以避免在rootScope中乱扔垃圾。rootScope更容易观看。


编辑:如果您想在数据准备就绪时继续检查控制器的方式,那么您希望 $scope.$watch 在数据加载后触发操作。