I use a factory as a singleton. I want to access the scope of a controller from this factory. It boils down to following code:
angular.module('foo', [])
.controller('fooCtrl', function($scope, testFac) {
$scope.example = "I wanna change";
testFac.change = function(change){
$scope.example = change;
}
})
.factory('testFac', function($timeout){
var testFac= {}
$timeout(function(){
testFac.change("You changed")
}, 3000)
return testFac;
})
at the moment im declaring the function in the controller, because then im in the right scope, and i can call the function from the factory. but it doesnt seem to be a very elegant solution. Is there a better way to solve this ? For testing purposes, see this fiddle
I use a factory as a singleton
Factories/Services/Providers are singletons
I want to access the scope of a controller from this factory.
Its not good practice to manipulate with scopes inside factory. In angular the scopes for controllers only to bind View to Controller.
About your code:
.factory('testFac', function($timeout){
var testFac= {}
$timeout(function(){
testFac.change("You changed")
}, 3000)
return testFac;
})
Its not purpose of factory. You can write second controller or directive
Is there a better way to solve this?
Yes, you can use $broadcast
Dispatches an event name downwards to all child scopes (and their children) notifying the registered $rootScope.Scope listeners.
I want to avoid using broadcast
Build a service with RxJS Extensions for Angular .
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/rx/dist/rx.all.js"></script>
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script>
var app = angular.module('myApp', ['rx']);
app.factory("DataService", function(rx, $timeout) {
var subject = new rx.Subject();
var data = "I wanna change";
$timeout(function(){
subject.onNext("You changed");
}, 3000);
return {
set: function set(d){
data = d;
subject.onNext(d);
},
get: function get() {
return data;
},
subscribe: function (o) {
return subject.subscribe(o);
}
};
});
Then simply subscribe to the changes.
app.controller('displayCtrl', function(DataService) {
var $ctrl = this;
$ctrl.data = DataService.get();
var subscription = DataService.subscribe(function onNext(d) {
$ctrl.data = d;
});
this.$onDestroy = function() {
subscription.dispose();
};
});
Clients can subscribe to changes with DataService.subscribe
and producers can push changes with DataService.set
.
angular.module('app', ['rx']) .factory("DataService", function(rx, $timeout) { var subject = new rx.Subject(); var data = "I wanna change"; $timeout(function(){ subject.onNext("You changed"); }, 3000); return { set: function set(d){ data = d; subject.onNext(d); }, get: function get() { return data; }, subscribe: function (o) { return subject.subscribe(o); } }; }) .controller('ctrl', function(DataService) { var $ctrl = this; $ctrl.data = DataService.get(); var subscription = DataService.subscribe(function onNext(d) { $ctrl.data = d; }); this.$onDestroy = function() { subscription.dispose(); }; })
<script src="//unpkg.com/angular/angular.js"></script> <script src="//unpkg.com/rx/dist/rx.all.js"></script> <script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script> <body ng-app="app" ng-controller="ctrl as $ctrl"> <h1>RxJS DEMO</h1> <p>Data= {{$ctrl.data}}</p> </body>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.