好的,所以我想出了如何使用 angular ui-router 来做到这一点,关键归结为 angular ui-router 在不影响 URL 的情况下转换状态的能力。
使其工作的步骤
- 首先将每个应用程序实例化为一个独立的应用程序,使用手动引导到一个 ID 元素。
- 将 ui-router $stateProvider 附加到每个应用程序以驱动内部状态转换(路由)。
- 您必须在此处为每个定义的状态保留 url 键,否则您将通过更改每个状态转换的 url 来重置页面。
- 在主控制器中设置状态函数以驱动状态变化。
以下是使其工作的代码:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.0.x" src="http://code.angularjs.org/1.0.7/angular.min.js" data-semver="1.0.7"></script>
<script src="angular-ui-states.min.js"></script>
<script src="app.js"></script>
</head>
<!-- define foo -->
<div id="fooApp" ng-controller="MainCtrl">
<ul class="menu">
<li><a href="#" ng-click="state('foo1')">foo1</a></li>
<li><a href="#" ng-click="state('foo2')">foo2</a></li>
</ul>
<div ui-view>
</div>
</div>
<script>
// Declare app level module which depends on filters, and services
var app = angular.module('fooApp', ['fooApp.controllers', 'ui.state']);
// Configure the app
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('foo1',
{
template: '<h1>Foo</h1><h2>foo1</h2>',
controller: 'MyCtrl1'
})
.state('foo2',
{
template: '<h1>Foo</h1><h2>foo2</h2>',
controller: 'MyCtrl2'
});
}]);
angular.module('fooApp.controllers', [])
.controller('MainCtrl', ['$scope', '$state', function($scope, $state){
$scope.state = function(name){
console.log('Transition to state ' + name);
$state.transitionTo(name);
}
}])
.controller('MyCtrl1', [function () {
console.log("fooApp.MyCtrl1 invoked.");
}])
.controller('MyCtrl2', [function () {
console.log("fooApp.MyCtrl2 invoked.");
}]);
// manually bootstrap
var div = document.getElementById('fooApp');
console.log(div);
angular.bootstrap(div, ['fooApp']);
</script>
<!-- define bar -->
<div id="barApp" ng-controller="MainCtrl">
<ul class="menu">
<li><a href="#" ng-click="state('bar1')">bar1</a></li>
<li><a href="#" ng-click="state('bar2')">bar2</a></li>
</ul>
<div ui-view>
</div>
</div>
<script>
// Declare app level module which depends on filters, and services
var app = angular.module('barApp', ['barApp.controllers', 'ui.state']);
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('bar1',
{
template: '<h1>Bar</h1><h2>bar1</h2>',
controller: 'MyCtrl1'
})
.state('bar2',
{
template: '<h1>Bar</h1><h2>bar2</h2>',
controller: 'MyCtrl2'
});
}]);
angular.module('barApp.controllers', [])
.controller('MainCtrl', ['$scope', '$state', function($scope, $state){
$scope.state = function(name){
console.log('Transition to state ' + name);
$state.transitionTo(name);
}
}])
.controller('MyCtrl1', [function () {
console.log("barApp.MyCtrl1 invoked.");
}])
.controller('MyCtrl2', [function () {
console.log("barApp.MyCtrl2 invoked.");
}]);
// manually bootstrap
var div = document.getElementById('barApp');
console.log(div);
angular.bootstrap(div, ['barApp']);
</script>
</body>
</html>
此解决方案的工作 plunker 在http://plnkr.co/edit/bXSN8qSMdioZJLYs2zyk?p=preview
请参阅我之前的回答,了解当前正在进行的讨论,以使 ui-router 中的 portlet 支持更加内在。