在解决控制器依赖关系时保持AngularJS的响应性
AngularJS在等待任何承诺的控制器依赖项解决时停止处理UI事件。如果这些依赖项中的任何一个依赖于挂起的API调用,则应用程序将变得无响应 如何设计一个AngularJS应用程序,在ui路由器解决外部控制器依赖关系时保持响应 咖啡脚本示例: 注入在解决控制器依赖关系时保持AngularJS的响应性,angularjs,coffeescript,dependencies,promise,angular-ui-router,Angularjs,Coffeescript,Dependencies,Promise,Angular Ui Router,AngularJS在等待任何承诺的控制器依赖项解决时停止处理UI事件。如果这些依赖项中的任何一个依赖于挂起的API调用,则应用程序将变得无响应 如何设计一个AngularJS应用程序,在ui路由器解决外部控制器依赖关系时保持响应 咖啡脚本示例: 注入accountBase的/accounts/:account\u id的路由定义: 控制器示例 在AngularJS中加载数据时,您有很多选择。以下三种方法对数据的呈现和可见性都有不同的影响 解析(在路由或状态中)-根据定义,这将停止页面的呈现,直
accountBase
的/accounts/:account\u id
的路由定义:
控制器示例
在AngularJS中加载数据时,您有很多选择。以下三种方法对数据的呈现和可见性都有不同的影响
- 解析(在路由或状态中)-根据定义,这将停止页面的呈现,直到所有解析值都完成加载。在您的示例中,您返回一个承诺,即ui路由器将在开始呈现/执行控制器函数之前解析哪个ui路由器。根据我的经验,最好少用这些,因为它们会导致一种波涛汹涌的体验
- 在控制器中,使用$resource并将get/query的返回值直接绑定到$scope
这将导致在$scope上放置一个空对象,一旦可用,它将被来自API调用的数据填充。这可能是可取的,也可能不是可取的,这取决于您正在显示的内容。在模板中,您可以检查$resolved属性var Foo = $resource('/api/foos'); // inject this into your controller // inside your controller function... $scope.foos = Foo.query();
,以显示数据正在加载的某种视觉提示。(另外,我不确定Restangular是否提供相同类型的“空对象”返回值,或者它是否只返回承诺。) 值得注意的是:您也可以用同样的方式使用解析。由于将返回一个对象(虽然该对象包含一个承诺,但不是一个承诺),因此渲染/控制器函数执行不会被延迟:ng show=“foos.$resolved”
resolve: { foos: function(Foo) { return Foo.query(); } }
- 为要显示的数据提供一些默认值,然后对$http或$resource调用使用success函数来填充实际值
$scope.data = { stuff: "none yet", things: "still waiting" }; // when the data is available, replace the defaults. Foo.get({id: 1}, function(data) { angular.extend($scope.data, data); });
- 缓存数据,以便用户下次访问该页面/路由时,您可以获得一个过时的副本。过时的数据通常比没有数据好。您可以使用在本地存储中存储东西,以实现跨会话的可用性—非常方便
- 若要在当前会话中保留数据,请使用单例来保留对数据的引用。任何注入以下服务的操作都将获得相同的对象实例(本例中为数组) 这是一个过于简单的示例,但是您可以返回一个包装器对象,该对象提供用于操作/重新加载数据的函数
deferred.resolve(base)解析解析函数中的承诺代码>,您的控制器被注入已解决的承诺。为了清楚起见,您可以执行deferred.resolve(结果)改为code>,以便将result
的值直接注入控制器
我刚刚查看了,我发现您可以返回promise的$object属性,以获得由$resource返回的相同类型的“要填充的空对象”,这将在不阻止渲染的情况下立即解决,等等。在AngularJS中加载数据时,您有很多选择。以下三种方法对数据的呈现和可见性都有不同的影响
- 解析(在路由或状态中)-根据定义,这将停止页面的呈现,直到所有解析值都完成加载。在您的示例中,您返回一个承诺,即ui路由器将在开始呈现/执行控制器函数之前解析哪个ui路由器。根据我的经验,最好少用这些,因为它们会导致一种波涛汹涌的体验
- 在控制器中,使用$resource并将get/query的返回值直接绑定到$scope
var Foo = $resource('/api/foos'); // inject this into your controller
// inside your controller function...
$scope.foos = Foo.query();
这将导致在$scope上放置一个空对象,一旦可用,它将被来自API调用的数据填充。这可能是可取的,也可能不是可取的,这取决于您正在显示的内容。在模板中,您可以检查$resolved属性ng show=“foos.$resolved”
,以显示数据正在加载的某种视觉提示。(另外,我不确定Restangular是否提供相同类型的“空对象”返回值,或者它是否只返回承诺。)
值得注意的是:您也可以用同样的方式使用解析。由于将返回一个对象(虽然该对象包含一个承诺,但不是一个承诺),因此渲染/控制器函数执行不会被延迟:
resolve: {
foos: function(Foo) {
return Foo.query();
}
}
- 为要显示的数据提供一些默认值,然后对$http或$resource调用使用success函数来填充实际值
$scope.data = {
stuff: "none yet",
things: "still waiting"
};
// when the data is available, replace the defaults.
Foo.get({id: 1}, function(data) {
angular.extend($scope.data, data);
});
还有几件值得注意的事情:
- 缓存数据,以便用户下次访问该页面/路由时,您可以获得一个过时的副本。过时的数据通常比没有数据好。您可以使用在本地存储中存储东西,以实现跨会话的可用性—非常方便
- 若要在当前会话中保留数据,请使用单例来保留对数据的引用。任何注入以下服务的操作都将获得相同的对象实例(本例中为数组)
这是一个过于简单的示例,但是您可以返回一个包装器对象,该对象提供用于操作/重新加载数据的函数
希望这有帮助
更新
值得一提的是,您的示例代码向后弯曲了一点以加载accountBase。因为您使用deferred.resolve(base)解析解析函数中的承诺代码>,您的控制器被注入