如何加载整个 AngularJs 应用程序使用的数据?
How to load data which is used by the entire AngularJs Application?
在我的应用程序中有一些数据被其他控制器用来完成他们的工作。
例如,我需要用户和其他一些实体对服务器进行 REST 调用。
目前我有一个 AppController (app.js)
,它加载将由所有 ng-views (see index.html).
的控制器使用的基本数据
函数 loadUser() and loadRequiredEntity()
将从 REST 调用接收到的值存储在 indexedDb
.
中
显示的 ng-views 的任何控制器 (see ng-view in index.html)
从 indexedDb
读取加载的数据。
我认为这种方法存在一些主要问题:
- AppController 是否会在 ng-view 的控制器尝试访问它们之前加载所有数据?
loadUser() and loadRequiredEntity()
调用服务(例如 userService),它执行 rest-calls 和 return promises 所以 AppController 在整个数据加载之前完成,对吧?所以 ng-views 的控制器在任何值存储在那里之前开始从 indexedDb 读取。
如何加载其他控制器需要的基本数据?
AngularJs 控制器是正确的选择吗?
index.html:
<body ng-app="app" id="appBody" ng-controller="AppController as appCtrl">
<md-content id="content" ng-view=""></md-content>
</body>
app.ts:
/// <reference path="../typings/tsd.d.ts" />
module app {
export class AppController {
static $inject = ['$log'];
private _LOG_PREFIX : string = 'AppController: ';
constructor(private $log: ng.ILogService) {
this.$log.info(this._LOG_PREFIX + 'started');
this.loadUser()
.then(this.loadRequiredEntity)
.then(this.markAsAuthenticated, this.handleLoadBasedataError);
}
...
}
}
正在访问数据:
您应该将数据存储在服务中,例如 UserService
。 $http
调用只能从服务进行。这是基于意见的,但很多人都同意,例如 this really popular style guide
在加载控制器之前加载数据: 在您的路由器配置中,您可以定义一个 resolve
选项(在 angular 默认路由器和 ui-路由器)。使用此 resolve
选项在访问您的应用页面之前加载数据。参见 ui router or in default router
- 解决,
call userService.load()
- 在每个控制器中,您可以访问数据,例如:
userService.getUsers()
正如 Melou 提到的 ui-router 解决了这个问题。
基础数据以抽象状态加载。
module app.core {
"use strict";
import LoadBasicDataService = app.core.services.LoadBasicDataService;
function loadBasicDataForControllers(loadBasicDataService: LoadBasicDataService) : ng.IPromise<any> {
return loadBasicDataService.load();
}
loadBasicDataForControllers.$inject = ['loadBasicDataService'];
function configureCore($urlRouterProvider: angular.ui.IUrlRouterProvider, $stateProvider: angular.ui.IStateProvider){
$urlRouterProvider.otherwise("/myComponent1");
$stateProvider
.state("main",{
templateUrl: "layout/main.html",
abstract: true,
resolve: {
'loadBasicDataForController': loadBasicDataForControllers
}
})
.state("main.myComponent2",{
url: "/myComponent2",
template: "<myComponent2></myComponent2>"
})
.state("main.myComponent1",{
url: "/myComponent1",
template: "<myComponent1></myComponent1>"
});
}
configureCore.$inject = ["$urlRouterProvider", "$stateProvider"];
angular
.module("app.core")
.config(configureCore);
}
在我的应用程序中有一些数据被其他控制器用来完成他们的工作。
例如,我需要用户和其他一些实体对服务器进行 REST 调用。
目前我有一个 AppController (app.js)
,它加载将由所有 ng-views (see index.html).
的控制器使用的基本数据
函数 loadUser() and loadRequiredEntity()
将从 REST 调用接收到的值存储在 indexedDb
.
显示的 ng-views 的任何控制器 (see ng-view in index.html)
从 indexedDb
读取加载的数据。
我认为这种方法存在一些主要问题:
- AppController 是否会在 ng-view 的控制器尝试访问它们之前加载所有数据?
loadUser() and loadRequiredEntity()
调用服务(例如 userService),它执行 rest-calls 和 return promises 所以 AppController 在整个数据加载之前完成,对吧?所以 ng-views 的控制器在任何值存储在那里之前开始从 indexedDb 读取。
如何加载其他控制器需要的基本数据? AngularJs 控制器是正确的选择吗?
index.html:
<body ng-app="app" id="appBody" ng-controller="AppController as appCtrl">
<md-content id="content" ng-view=""></md-content>
</body>
app.ts:
/// <reference path="../typings/tsd.d.ts" />
module app {
export class AppController {
static $inject = ['$log'];
private _LOG_PREFIX : string = 'AppController: ';
constructor(private $log: ng.ILogService) {
this.$log.info(this._LOG_PREFIX + 'started');
this.loadUser()
.then(this.loadRequiredEntity)
.then(this.markAsAuthenticated, this.handleLoadBasedataError);
}
...
}
}
正在访问数据:
您应该将数据存储在服务中,例如 UserService
。 $http
调用只能从服务进行。这是基于意见的,但很多人都同意,例如 this really popular style guide
在加载控制器之前加载数据: 在您的路由器配置中,您可以定义一个 resolve
选项(在 angular 默认路由器和 ui-路由器)。使用此 resolve
选项在访问您的应用页面之前加载数据。参见 ui router or in default router
- 解决,
call userService.load()
- 在每个控制器中,您可以访问数据,例如:
userService.getUsers()
正如 Melou 提到的 ui-router 解决了这个问题。
基础数据以抽象状态加载。
module app.core {
"use strict";
import LoadBasicDataService = app.core.services.LoadBasicDataService;
function loadBasicDataForControllers(loadBasicDataService: LoadBasicDataService) : ng.IPromise<any> {
return loadBasicDataService.load();
}
loadBasicDataForControllers.$inject = ['loadBasicDataService'];
function configureCore($urlRouterProvider: angular.ui.IUrlRouterProvider, $stateProvider: angular.ui.IStateProvider){
$urlRouterProvider.otherwise("/myComponent1");
$stateProvider
.state("main",{
templateUrl: "layout/main.html",
abstract: true,
resolve: {
'loadBasicDataForController': loadBasicDataForControllers
}
})
.state("main.myComponent2",{
url: "/myComponent2",
template: "<myComponent2></myComponent2>"
})
.state("main.myComponent1",{
url: "/myComponent1",
template: "<myComponent1></myComponent1>"
});
}
configureCore.$inject = ["$urlRouterProvider", "$stateProvider"];
angular
.module("app.core")
.config(configureCore);
}