Reputation: 28180
We have several controllers in an application, for several different tabs/pages. I want to have some mechanism to indicate that something is finished in one of them for use in another controller. Promises should be this mechanism, so I am trying to get a hang of it.
I have played around at http://jsfiddle.net/ExN6Q/ and gotten something that works like I want, but I am not super happy with the result for the services.
If I have the following html:
<div ng-app="myApp">
<div ng-controller=myController1>
Fill in this field: <input type="text">
<input type="submit" value="Done" ng-click="submit()">
</div>
<div ng-controller=myController2 ng-show="done1">
And this field: <input type="text">
<input type="submit" value="Done" ng-click="submit()">
</div>
<div ng-controller=myController3 ng-show="done2">
As well as this field: <input type="text">
<input type="submit" value="Done" ng-click="submit()">
</div>
</div>
and then the following controllers:
my_module.controller('myController1', function ($scope, Done1Service) {
$scope.submit = Done1Service.done;
});
my_module.controller('myController2', function ($scope, Done1Service, Done2Service) {
$scope.done1 = false;
$scope.submit = Done2Service.done;
Done1Service.get_promise().then(function () {
$scope.done1 = true;
});
});
my_module.controller('myController3', function ($scope, Done2Service, Done3Service) {
$scope.done2 = false;
$scope.submit = Done3Service.done;
Done2Service.get_promise().then(function () {
$scope.done2 = true;
});
Done3Service.get_promise().then(function () {
alert("Congratulations, you're done!");
});
});
then I am actually satisfied with the result, the "problem" is the implementation of the services:
my_module.factory('Done1Service', function ($q) {
var deferred = $q.defer();
var get_promise_fn = function () {
return deferred.promise;
};
var done_fn = function () {
console.log("I'm done!");
return deferred.resolve(true);
};
return {
get_promise: get_promise_fn,
done: done_fn
};
});
my_module.factory('Done2Service', function ($q) {
... // identical except console.log("I'm done again!")
});
my_module.factory('Done3Service', function ($q) {
... // identical except console.log("I'm done at last!");
});
These feel a bit too boilerplatish, and I wonder if I am doing something wrong. Could I create one common service and make three instances of it? Is this the normal way to handle this by returning a promise from a dedicated get_promise function ( which I then assume would probably be called something else)?
Upvotes: 0
Views: 42
Reputation: 43718
As it is right now, your services are a one shot deal since promises cannot be reset. I think you could solve this problem by either using a single EventBus
service through which every controllers communicates. E.g. The first controller sends a 'step1completed' message on the bus which is intercepted by the second controller, which does it's work and fires a 'step2completed' event, etc.
If you have many identical processes that have to run in parallel, you could allow creating multiple EventBus
instances which would serve as independent communication channels for a specific set of objects.
Angular already allow you to emit or broadcast events through scopes, have a look at $emit
and $broadcast
.
Upvotes: 1