angular.module('demoApp', [])
\t .controller('MainController', MainController)
\t .directive('component1', Component1)
\t .directive('component2', Component2)
.directive('component3', Component3)
\t .factory('sharedData', SharedData)
\t .factory('sharedDataEvents', SharedDataEvents);
function MainController(sharedData) {
sharedData.setItems([{
id: 0,
test: 'hello 0'
}, {
id: 1,
test: 'hello 1'
}, {
id: 2,
test: 'hello 2'
}]);
this.items = sharedData.getItems();
\t this.selection = this.items[0];
}
function Component1() {
return {
\t restrict: 'E',
scope: {},
bindToController: {
\t selection: '='
},
template: 'Comp1 selection: {{comp1Ctrl.selection}}'+
'<ul><li ng-repeat="item in comp1Ctrl.items" ng-click="comp1Ctrl.select(item)">{{item}}</li></ul>',
controller: function($scope, sharedData, sharedDataEvents) {
this.items = sharedData.getItems();
this.select = function(item) {
//console.log(item);
this.selection = item
\t sharedData.setSelection(item);
};
sharedDataEvents.addListener('onSelect', function(selected) {
\t console.log('selection changed comp. 1 listener callback', selected);
});
},
controllerAs: 'comp1Ctrl'
};
}
function Component2() {
return {
\t restrict: 'E',
scope: {},
bindToController: {
\t selection: '@'
},
template: 'Comp2 selection: {{comp2Ctrl.selection}}',
controller: function(sharedDataEvents) {
sharedDataEvents.addListener('onSelect', function(selected) {
\t console.log('selection changed comp. 2 listener callback', selected);
});
},
controllerAs: 'comp2Ctrl'
};
}
function Component3() {
\t //only listening and alert on every third change
return {
\t restrict: 'E',
controller: function($window, sharedDataEvents) {
\t var count = 0;
sharedDataEvents.addListener('onSelect', function(selected, old) {
\t console.log('selection changed comp. 3 listener callback', selected, old);
if (++count === 3) {
count = 0;
\t $window.alert('changed selection 3 times!!! Detected by Component 3');
}
});
}
}
}
function SharedData(sharedDataEvents) {
return {
\t selection: {},
items: [],
setItems: function(items) {
\t this.items = items
},
setSelection: function(item) {
\t this.selection = item;
sharedDataEvents.onSelectionChange(item);
},
getItems: function() {
\t return this.items;
}
};
}
function SharedDataEvents() {
\t return {
changeListeners: {
\t onSelect: []
},
addListener: function(type, cb) {
\t this.changeListeners[type].push({ cb: cb });
},
onSelectionChange: function(selection) {
console.log(selection);
var changeEvents = this.changeListeners['onSelect'];
console.log(changeEvents);
if (! changeEvents.length) return;
\t angular.forEach(changeEvents, function(cbObj) {
console.log(typeof cbObj.cb);
if (typeof cbObj.cb == 'function') {
// callback is a function
if (selection !== cbObj.previous) { // only trigger if changed
cbObj.cb.call(null, selection, cbObj.previous);
cbObj.previous = selection; // new to old for next run
}
}
});
}
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.js"></script>
<div ng-app="demoApp" ng-controller="MainController as ctrl">
<p>Click on a list item to change selection:</p>
<component1 selection="ctrl.selection"></component1> <!-- can change the selection -->
<component2 selection="{{ctrl.selection}}"></component2>
<component3></component3>
</div>
是否整個應用程序需要知道currentSelection,或網站的某一部分?也許將這些信息存儲在所有涉及的指令/控制器的共享父控制器中。你可以分享一些涉及的代碼(可能是在一個笨蛋?) –
這是一個網絡應用程序,所以當你做出選擇時,其他一些組件需要知道 - 這是事件運行良好的一部分 - 此外它也可以單程。共享一個父範圍值可能會起作用,但我仍然存在的擔憂 - 範圍上的任何內容都可以設置該值。我可能更喜歡一種服務,這樣我們就可以使我們成爲DI,並避免潛在的命名衝突。 – helion3
您能否解釋一下對於預期的$ watch功能感覺複雜的問題 - 您打算如何實現這一功能? –