【发布时间】:2015-03-19 22:52:13
【问题描述】:
我正在为我们的客户支持构建一个 Web 应用程序。需求之一是能够同时打开多张票。
我能够使用制表系统和 UI-Router 轻松完成第一部分。
但是,在我当前的实现中,每次更改活动选项卡时,都会卸载先前的当前选项卡,并加载现在的当前选项卡(因为它是通过先前的选项卡更改卸载的)。
这根本不是预期的行为。我已经花了几天的时间试图找到实现这一目标的方法,但没有任何运气。 我能做的最接近的事情是使用 UI-Router 的多视图系统,但我需要同一视图的多个实例来保存在内存中(如果打开了多个票证,它们都在同一个视图中,并且相同的控制器,但范围不同)
这是我当前的实现: 支持应用程序.js: var app = angular.module("supportApp", ["ui.router", "ui.bootstrap"]);
app.config(function($stateProvider, $urlRouterProvider, $httpProvider){
$urlRouterProvider.otherwise("/");
$stateProvider
.decorator('d', function(state, parent){
state.templateUrl = generateTemplateUrl(state.self.templateUrl);
return state;
})
.state("main", {
abtract: true,
templateUrl: "main.html",
controller: "mainController"
})
.state("main.inbox", {
url: "/",
templateUrl: "inbox.html",
controller: "inboxController"
})
.state('main.viewTicket', {
url: '/ticket/{id:int}',
templateUrl: "viewTicket.html",
controller: "ticketController"
})
;
});
mainController.js:(处理其他东西,这里的代码最少)
app.controller("mainController", function($rootScope, $http, $scope, $state, $interval){
// Tabs system
$scope.tabs = [
{ heading: "Tickets", route:"main.inbox", active:false, params:{} }
];
var addTabDefault = {
heading: '',
route: null,
active: false,
params: null,
closeable: false
};
$rootScope.addTab = function(options){
if(!options.hasOwnProperty('route') || !options.route)
{
throw "Route is required";
}
var tabAlreadyAdded = false;
for(var i in $scope.tabs)
{
var tab = $scope.tabs[i];
if(tab.route == options.route && angular.equals(tab.params, options.params))
{
tabAlreadyAdded = true;
break;
}
}
if(!tabAlreadyAdded)
{
$scope.tabs.push($.extend({}, addTabDefault, options));
}
if(options.hasOwnProperty('active') && options.active === true)
{
$state.go(options.route, options.hasOwnProperty('params')?options.params:null);
}
};
$scope.removeTab = function($event, tab){
$event.preventDefault();
if($scope.active(tab.route, tab.params))
{
$scope.go($scope.tabs[0].route, $scope.tabs[0].params);
}
$scope.tabs.splice($scope.tabs.indexOf(tab), 1);
};
$scope.go = function(route, params){
$state.go(route, params);
};
$scope.active = function(route, params){
return $state.is(route, params);
};
$scope.$on("$stateChangeSuccess", function() {
$scope.tabs.forEach(function(tab) {
tab.active = $scope.active(tab.route, tab.params);
});
});
});
main.html:
<div class="container-fluid" id="sav-container">
<div class="row-fluid">
<div class="col-lg-2">
<form role="form" id="searchForm" action="#">
<div class="form-group has-feedback">
<input class="form-control" type="search" />
<span class="glyphicon glyphicon-search form-control-feedback"></span>
</div>
</form>
</div>
<div class="col-lg-10" id="support_main_menu">
<ul class="nav nav-tabs">
<li ng-repeat="t in tabs" ng-click="go(t.route, t.params)" ng-class="{active: t.active, closeable: t.closeable}" style="max-width: calc((100% - 128px) / {{tabs.length}});">
<a href class="nav-tab-text">
<button ng-show="t.closeable" ng-click="removeTab($event, t)" class="close" type="button">×</button>
<span>{{t.heading}}</span>
</a>
</li>
</ul>
</div>
</div>
<div class="row-fluid">
<div class="tab-content" ui-view></div>
</div>
</div>
在我看来,我的要求很标准,但我很遗憾在互联网上找不到任何有用的东西
【问题讨论】:
-
所以基本上你想在改变路由并实例化另一个控制器时让一个控制器保持“活动”?是吗?
-
基本上就是这样,是的
-
我相信你不能那样做,因为一旦你改变状态,控制器就会被销毁,这就是控制器的工作方式。我认为你是否将范围的内容放在缓存中,然后在控制器再次实例化时检索它,或者你在单个控制器上创建所有选项卡。
标签: angularjs angular-ui-router