我正在完成面包屑系统的紧凑实现,它支持弹出窗口和制表符管理。
<div>
<a href="" ng-click="breadcrumbs.back()">< BACK</a> | Showing <em>'{{currentTab}}'</em>
</div>
<div
class="popover"
ng-repeat="p in popovers">
<div>
Popover name: {{p.displayName}}
</div>
<div ng-repeat="t in p.tabs"
class="tab"
ng-class="$parent.currentTab==t.name?'selected':''"
ng-click="$parent.$parent.currentTab=openTab(t.name)">
{{t.name}}
</div>
<div ng-repeat="t in p.tabs"
class="tabContent"
ng-class="currentTab==t.name?'selected':''">
<p>{{t.displayName}}</p>
</div>
</div>
<hr>
<p>currentTab={{currentTab}}</p>
<p>Breadcrumbs : {{breadcrumbs.urls.length}} levels</p>
<ol>
<li ng-repeat="url in breadcrumbs.urls">
— {{$index}}: {{url.url}} | {{url.tab}}
</li>
</ol>
app.controller('myCtrl', function ($scope, $location, $http) {
$scope.currentTab = $scope.currentTab||'Tab2';
console.log("========= controller started =========");
console.log("currentTab is '"+$scope.currenTab+"'");
$scope.openTab = function(tab) {
$scope.breadcrumbs.openUrl($scope.getPage()+"?openTab="+tab);
return tab;
};
$scope.getPage = function() {
//console.log("getPage() returns "+$location.path());
return $location.path();
};
//-- Breadcrumb management
$scope.breadcrumbs = {
urls:[],
push: function(url){
this.urls.push(url);
},
back: function(){
if (this.urls.length<1) {
console.log("Breadcrumb: *** error back() requested but no URLs stored. Ignoring…");
return;
}
var current = this.urls[this.urls.length-1];
// pull the current url out of the breadcrumbs stack
this.urls.splice(-1);
var target = this.urls.length?this.urls[this.urls.length-1]:{url:'home', popup:null};
openPopupOnLoad = target.popup;
console.log("Breadcrumb: back from url "+current.url+" is asked");
this.log("back(url "+target.url+", popup "+target.popup+", tab "+target.tab+")");
if (current.url==target.url) {
//$timeout(function(){
$scope.currentTab = target.tab;
$scope.$apply($scope.currentTab);
console.log("Breadcrumb: stay on the url "+target.url+" but set currentTab to "+$scope.currentTab);
//},300);
}
else {
openTabOnLoad = target.tab;
console.log("Breadcrumb: back to url "+target.url+" (set openTabOnLoad to "+openTabOnLoad);
$location.url(target.url);
}
},
registerOpenTab: function(tab) {
var url = $scope.getPage();
if (url.substr(0,1)=='/') url = url.substr(1);
console.log("::::: Breadcrumbs --- registerOpenTab tab "+tab+" from url "+url);
// push target
var target = {url: url, popup: null, tab: tab};
this.push(target);
this.log("registerOpenTab("+tab+")");
},
openUrl: function(fullUrl) {
openPopupOnLoad = null;
//openTabOnLoad = null;
// look at target url if popup is requested to open?
var popup = null;
var tab = null;
var url = fullUrl;
var i = fullUrl.indexOf("?");
if (i!=-1) {
url = url.substr(0,i);
}
if (url.substr(0,1)=='/') url = url.substr(1);
console.log("::::: Breadcrumbs --- asked to openUrl "+fullUrl);
i = fullUrl.indexOf("openPopup=");
if (i!=-1) {
popup = fullUrl.substr(i+10);
i = popup.indexOf("&");
if (i!=-1) {
popup = popup.substr(0,i);
}
}
i = fullUrl.indexOf("openTab=");
if (i!=-1) {
tab = fullUrl.substr(i+8);
i = tab.indexOf("&");
if (i!=-1) {
tab = tab.substr(0,i);
}
}
// get current page
var current = this.urls.length?this.urls[this.urls.length-1]:null;
if (!current) {
current = {url: $scope.getPage()};
if (current.url.substr(0,1)=='/') current.url = current.url.substr(1);
}
console.log("::::: Breadcrumbs --- got url "+url+" with popup "+popup+" and tab "+tab+"(current url is "+(current?current.url:null)+")");
// - handle potential popup
// if target url is same page…
if (popup) {
if (current.url==url) {
//this.log("openUrl("+url+", "+popup+")");
console.log("::::: Breadcrumbs --- already on the url "+url+" only open popup "+popup);
$scope.openPopover("#"+popup);
return;
}
else {
openPopupOnLoad = popup;
console.log("::::: Breadcrumbs --- recorded to open popup on load "+popup);
}
}
// - handle potential tab
if (tab) {
//$scope.currentTab = openTabOnLoad = tab;
console.log("::::: Breadcrumbs --- recorded to open tab on load "+tab);
url +="?openTab="+tab;
}
// - push target
var target = {url: url, popup: popup, tab: tab};
this.push(target);
console.log("::::: Breadcrumbs --- have to redirect to url "+url+" to open popup "+popup+ " or tab "+tab);
this.log("openUrl("+url+", "+popup+", "+tab+")");
$location.url(url);
},
log: function(text) {
text = text||" (unknown call origin)";
console.log("::::: Breadcrumbs -----------------------------------+");
console.log("::::: Breadcrumbs --- > log("+text+")");
for (var i in this.urls) {
var t = this.urls[i];
console.log("::::: Breadcrumbs --- "+i+" url: "+t.url+"\tpopup: "+t.popup+"\ttab: "+t.tab);
}
console.log("::::: Breadcrumbs ---[openPopupOnLoad\t="+openPopupOnLoad+"] <");
console.log("::::: Breadcrumbs ---[openTabOnLoad\t="+openTabOnLoad+"] and currentTab set to "+$scope.currentTab+"<");
console.log("::::: Breadcrumbs -----------------------------------+");
}
};
});
代码运行良好,除了当我运行back()作用域方法时,虽然currentTab在控制器中更新,但它不会反映在HTML部分中。尽管做了很多实验,我仍然陷入困境。
我给你一个jsFiddle在那里玩:http://jsfiddle.net/stephanedeluca/smxt8d1e/
答案 0 :(得分:0)
工作小提琴 - http://jsfiddle.net/smxt8d1e/22/
这里做了几件事......
1。)将初始状态作为第一个条目推送到urls数组
// line 32
if (this.urls.length==1) {...}
// line 205
$scope.openTab($scope.currentTab);
2.。)删除了$apply
声明
// line 51
//$scope.$apply($scope.currentTab);
3。)即使在$scope.currentTab
current.url!=target.url
// line 58
$scope.currentTab = openTabOnLoad;
据我所知,标签现在可以正常切换。