避免手錶
的事件將是合適的方式去爲這種需求,怎麼樣alex指出。一個普拉克展示一個例子:http://plnkr.co/edit/v6OXjOXZzF9McMvtn6hG?p=preview
但對於這種特殊的情況下,我不認爲「角辦法」是「的方式」。鑑於$broadcast
和/或$emit
如何工作(即默認方式事件工作在角度),我會避免它們...(閱讀docs以瞭解原因)。簡而言之,這些機制旨在觸發聽衆(附加到某個範圍)向上/向下的範圍層次。你並不需要那麼多。 (Ref code for $emit
)
我通常會依賴其他事件傳播機制(考慮這種需求模式)。
app.controller('MainCtrl', function($scope, SessionService, $document){
// You will want to invoke attachUser some other way (perhaps on authentication), this is for test purposes only
$scope.isLoggedIn = false;
$document.bind('$loggedin', function(){
$scope.isLoggedIn = true;
$scope.user = SessionService.fName;
});
$scope.logout = function() {
SessionService.attachUser(null, null);
$scope.isLoggedIn = false;
};
});
app.controller('LoginCtrl', function($scope, SessionService, $document){
$scope.doLogin = function() {
console.log('doLogin');
SessionService.attachUser(1234, $scope.username);
var doc = $document[0];
var evt = new Event('$loggedin');
doc.dispatchEvent(evt);
};
});
Plunk
當然,當你用這個觀點,總是清理完成。處理設備上那些控制器的範圍$destroy
事件和取消綁定事件處理程序...
$scope.$on('$destroy', function() {
$document.unbind('$loggedin');
};
參考MDN更多關於如何觸發使用DOM事件。
更新:[9月24日]
這裏是一個小指令設置,其中說明了這一點:
app.directive('ngNest', function($parse, $compile, $timeout){
var end = false;
var level = 0;
var fnPostLink = function(scope, element, attrs) {
//console.log('start:', ++fnPostLink.count);
var lvl = attrs.level;
if(!lvl) {
throw 'Level not specified';
}
var create = document.createElement.bind(document);
var level = parseInt(lvl);
var count = 0;
var div = create('div');
div.setAttribute('ng-controller', 'DummyCtrl');
var cls = function() {
return 'margin ' + (count % 2 ? 'even' : 'odd');
//return 'margin even';
};
div.setAttribute('class', cls());
var node = div;
while(count++ < level - 1) {
var child = create('div');
child.setAttribute('ng-controller', 'DummyCtrl');
child.setAttribute('class', cls());
node.appendChild(child);
node = child;
}
node.setAttribute('ng-controller', 'FinalCtrl');
node.innerHTML = 'foo';
var $new = $compile(div)(scope);
var el = element;
el.append($new);
};
fnPostLink.count = 0;
var fnPreLink = function(scope, element, attrs) {
//console.log('prelink');
};
var api = {
link: {
post: fnPostLink,
pre: fnPreLink
},
template: '<div></div>',
scope: {},
restrict: 'E',
replace: true
};
return api;
});
它簡單地嵌套的div附加控制器給它。我附加了這兩個控制器:
app.controller('DummyCtrl', function($scope){
});
app.controller('FinalCtrl', function($scope, $document){
$scope.$on('$myEvt', function(){
console.log('$myEvt', $scope.$id, new Date().getTime());
});
$document.bind('$myEvt', function(){
console.log('$myEvt', $scope.$id, new Date().getTime());
});
});
FinalCtrl被添加到尾部; DummyCtrl被添加到其餘的。
在HTML模板我做這樣的事情:
<ng-nest level="10"></ng-nest>
也有在HTML文件中嵌套的標記被手動放在那裏......
整個代碼可以在這裏找到:https://gist.github.com/deostroll/a9a2de04d3913f021f13
這裏是我獲得從我的瀏覽器中運行的結果:
Live reload enabled.
$broadcast 1443074421928
$myEvt 14 1443074421929
$myEvt 19 1443074421930
DOM 1443074426405
$myEvt 14 1443074426405
$myEvt 19 1443074426405
當我完成$廣播時,您可以注意到滴答的差異。我在$ rootScope上完成了$廣播;因此沿着作用域樹深度優先,並觸發那些監聽器附加相應的作用域,以這種順序 ... $ stuff & $廣播源代碼也驗證了這一事實。
更好的選擇是使用登錄服務[documentation here](https://docs.angularjs.org/guide/services)。這樣你可以根據需要注入不同模塊的服務。 – alex
@alex - 這可能是答案... OP正在尋找正確的方式做到這一點...也許你應該充實和發佈回答... – DrCord
我添加了服務,這是我的第一個想法,但我不能使它工作 – EsseTi