为了解耦样式、数据、内容等的动态变化,通常需要创建另一个 Angular 模块,其中包含一个接口(自定义提供者),该接口可以让您在配置级别之前和之后访问这些更改。这里有一个
plunker,以便提供下面将要讨论的内容。
对于这个答案,我创建了一个小模块(route-data.js),其中包含一个提供者(RouteData),它公开了两个函数配置:
applyConfig()
- 分配要在 RouteData 服务中访问的设置。
hookToRootScope()
- 将 RouteData 服务挂钩在
$rootScope
中,从而使其可用于将要创建的所有子作用域和整个应用程序。
RouteData 提供程序具有一个
RouteData()
服务,该服务提供了访问方法,用于设置和获取将在
$routeProvider
配置中提供的
RouteData
设置。
(如果您不熟悉提供者和服务,请在
here阅读更多信息)
如果您不熟悉config()
和run()
方法,可以在这里阅读更多信息。
route-data.js
angular.module('RouteData', []).
provider('RouteData', function () {
var settings = {};
var hookToRootScope = false;
this.applyConfig = function(newSettings) {
settings = newSettings;
};
this.hookToRootScope = function(enableRootScopeHook) {
hookToRootScope = enableRootScopeHook;
};
function RouteData() {
this.set = function(index, value) {
settings[index] = value;
};
this.get = function(index) {
if(settings.hasOwnProperty(index)) {
return settings[index];
} else {
console.log('RouteData: Attempt to access a propery that has not been set');
}
};
this.isHookedToRootSope = function() {
return hookToRootScope;
};
}
this.$get = function() {
return new RouteData();
};
}).
run(['$location', '$rootScope', 'RouteData', function($location, $rootScope, RouteData) {
if(RouteData.isHookedToRootSope()) {
$rootScope.RouteData = RouteData;
}
$rootScope.$on('$routeChangeStart', function(event, current, previous) {
var route = current.$$route;
if(typeof(route) !== 'undefined' && typeof(route['RouteData']) !== 'undefined') {
var data = route['RouteData'];
for(var index in data)
RouteData.set(index, data[index]);
}
});
}]);
以下脚本展示了如何通过在配置级别注入RouteDataProvider来使用上述的RouteData模块,并应用默认配置,例如通过RouteDataProvider.applyConfig()设置bodyStyle。在应用程序完全运行之前,您还可以添加更多设置。通过将RouteDataProvider.hookToRootScope()设置为true,在$rootScope中连接它。最后,附加数据,例如RouteData。
RouteData: {
bodyStyle: {
'background-color': 'green'
}
}
由$routeProvider发送并由RouteData模块中定义的run()方法处理,该方法初始化RouteData服务的设置以便在应用程序中访问。
script.js
angular.module('app', ['ngRoute', 'RouteData']).
config(['$routeProvider', 'RouteDataProvider', function($routeProvider, RouteDataProvider) {
RouteDataProvider.applyConfig({
bodyStyle: {
'background-color': 'white'
}
});
RouteDataProvider.hookToRootScope(true);
$routeProvider.when('/landing', {
RouteData: {
bodyStyle: {
'background-color': 'green'
}
},
templateUrl: 'landing.html',
controller: 'LandingController'
}).when('/login', {
RouteData: {
bodyStyle: {
'background-color': 'gray',
padding: '10px',
border: '5px solid black',
'border-radius': '1px solid black'
}
},
templateUrl: 'login.html',
controller: 'LoginController'
}).otherwise({
redirectTo: '/landing'
});
}]).
controller('LoginController', ['$scope', function($scope) {
}]).
controller('LandingController', ['$scope', function($scope) {
}]);
因此,最终需要添加到您的主页或任何其他页面的代码将类似于以下内容。
index.html
的一部分
<body ng-style="RouteData.get('bodyStyle')">
<a href="#/landing">Landing</a> |
<a href="#/login">Login</a>
<div ng-view></div>
</body>