我想做这样的事情:
app.config(function($routeProvider){
$routeProvider.when('products/list', {
controller: 'ProductListCtrl',
templateUrl : 'products/list/view.html',
resolve : { data : function(){
...
},
loadingTemplateUrl : 'general/loader.html'
}
});
我希望将加载页面放在不同的视图中。
这将使每个页面的视图和控制器中的代码更清晰(没有< ... ng-include ng-show =" loading" ...>)。这也意味着我不需要$ scope。$观察数据的变化。是否有一个干净的解决方案来执行类似的操作(不一定在.config方法中)或替代库来执行此操作?
答案 0 :(得分:0)
假设您想在解析数据时显示所有状态转换的一般模板,我的建议是监听路由库触发的事件。这允许使用一个中心点来处理所有状态转换,而不是污染路由配置(我认为这不是那么容易)。
查看$routeChangeStart
,$routeChangeSuccess
以及$routeChangeError
的文档
答案 1 :(得分:0)
也许某人可能对我所做的事感兴趣:我创建了一个新服务和一个新的视图指令。看起来似乎很多工作,但这样做比我想象的要容易得多。新服务使我能够将主视图与加载视图分开,我可以在应用程序的所有页面中重用该视图。我还提供了配置错误模板URL和错误控制器的可能性,用于加载失败时。
Angular $ injector,$ templateRequest和$ controller服务完成了大部分工作。我只需要将一个依赖于这些服务的指令连接到正确的事件($ locationChangeSuccess),并将其从解析对象的函数中检索(使用$ q.all)。此连接在路由服务中完成。该服务选择正确的模板url和comtroller,并将其传递给指令以进行处理。
缩短版本(省略了getCurrentConfig方法):
RouteService:
(function () {
'use strict';
// provider:
angular.module('pikcachu')
.provider('pikaRouteService', [function () {
var routeConfigArray;
var otherwiseRouteConfig;
//configuration methods
this.when = function (url, routeConfig){
routeConfigArray.push({url: url, routeConfig: routeConfig});
return this;
}
this.otherwise = function(routeConfig){
otherwiseRouteConfig = routeConfig;
return this;
}
// service factory:
this.$get = ['$rootScope', '$location', '$q', '$injector', '$templateRequest',
function ($rootScope, $location, $q, $injector, $templateRequest) {
function RouteService() {
this.setViewDirectiveUpdateFn = function(){ /*...*/ }
function init(){
$rootScope.$on('$locationChangeSuccess', onLocationChangeSuccess);
}
function onLocationChangeSuccess(){
// get the configuration based on the current url
// getCurrentConfig is a long function, because it involves parsing the templateUrl string parameters, so it's left out for brevity
var currentConfig = getCurrentConfig($location.url());
if(currentConfig.resolve !== undefined){
// update view directive to display loading view
viewDirectiveUpdateFn(currentConfig.loadingTemplateUrl, currentConfig.loadingController);
// resolve
var promises = [];
var resolveKeys = [];
for(var resolveKey in currentConfig.resolve){
resolveKeys.push(resolveKey);
promises.push($injector.invoke(resolve[resolveKey]));
}
$q.all(promises).then(resolveSuccess, resolveError);
function resolveSucces(resolutionArray){
// put resolve results in an object
var resolutionObject = {};
for(var i = 0; i< promises.length;++i){
resolved[resolveKeys[i]] = resolutionArray[i];
}
viewDirectiveUpdateFn(currentConfig.errorTemplateUrl, currentConfig.errorController);
}
function resolveError(){
viewDirectiveUpdateFn(currentConfig.errorTemplateUrl, currentConfig.errorController);
}
}
}
init();
}
return new RouteService();
}]
})();
查看指令
(function () {
'use strict';
angular.module('pikachu')
.directive('pikaView', ['$templateRequest', '$compile', '$controller', 'pikaRouteService', function ($templateRequest, $compile, $controller, pikaRouteService) {
return function (scope, jQdirective, attrs) {
var viewScope;
function init() {
pikaRouteService.listen(updateView);
}
function updateView(templateUrl, controllerName, resolved) {
if(viewScope!== undefined){
viewScope.$destroy();
}
viewScope = scope.$new();
viewScope.resolved = resolved;
var controller = $controller(controllerName, { $scope: viewScope });
$templateRequest(templateUrl).then(onTemplateLoaded);
function onTemplateLoaded(template, newScope) {
jQdirective.empty();
var compiledTemplate = $compile(template)(newScope);
jQdirective.append(compiledTemplate);
}
}
init();
};
}
]);
})();