I am trying to display a spinner during page load using angular $emit and a command file. My model is:
Model:
model.load = function(){
model.loading = true;
$rootScope.$emit('loadMyPage', model.loading);
return service.getData().then(storesResult, storesFault);
}
var storesResult = function (value) {
model.categoriesLoading = false;
$rootScope.$emit('loadMyPage', model.loading);
model.stores = value.result;
saveData();
};
var storesFault = function (value) {
var data = value.data;
var status = value.status;
model.categoriesLoading = false;
model.stores = null;
$rootScope.$emit('loadMyPage', model.loading);
$rootScope.$emit('systemAlert', {title: 'Loading Error', message: data, status: status, type: 'danger', timeout: 10000, showAsModal: true});
return value;
};
My Command file which is executed in app.run
command.execute = function () {
$rootScope.$on('loadMyPage', onLoadingChange);
};
var onLoadingChange = function (event, value) {
if (model.loading === true) {
showModal('sections/modals/loading/loading.tpl.html');
} else {
hideModal();
}
};
};
The problem is during page load the $emit from model.load does not go to $on in command. When the $on is called it is done from the storesResult block. As a result model.loading is always getting false. This can be an async issue.
All suggestions are welcome.
Maybe don't use $emit and $on. If you have the $rootscope object, just make a key with your key value pair or whatever data you want to check for. Your data may be there as you would expect, or use $watch to wait for it, or just use a callback with $rootscope.
HOWEVER
Maybe $rootScope is not the best idea to pollute with attributes. I'll leave that one up to you.
ALSO
A quick help out on $emit and $broadcast
Controllers are instantiated, with $scope DI'd => link ( not singletons );
This is how broadcast and emit work. Notice the nodes below; all nested within node 3. You use broadcast and emit when you have this scenario.
Check out this tree. How do you answer the following questions? note: There are other ways, but here we'll discuss broadcast and emit. Also, when reading below text assume each number has it's own file (directive, controller) e.x. one.js, two.js, three.js.
In file one.js
In file three.js
In file two.js
In file three.js
In file three.js
In file one.js && two.js whichever file you want to catch the message.
In file two.js
In file three.js
In file one.js
HOWEVER
When you have all these nested child nodes trying to communicate like this, you will quickly see many $on's $broadcast's, and $emit's. Here is what I like to do.
In PARENT NODE ( three in this case... )
So, in file three.js
Now in any of the child nodes you only need to $emit the message or catch it using $on.
NOTE: It is normally quite easy to cross talk in one nested path without using $emit, $broadcast, or $on, which means most use cases are for when you are trying to get 1 to communicate with 2 or vice versa.
In file two.js
In file three.js
In file one.js
You will still need to use $on with each specific value you want to catch, but now you can create whatever you like in any of the nodes without having to worry about how to get the message across the parent gap.
Hope this helps...