Events and view cacheing stops event listeners totally also if i disable caching at all :-(


#1

Hey!

I have a problem, i have a profile page that should display userdata.
In the profiles controller i have listen on an event => currentUserUpdated

  var onCurrentUserUpdatedHandler = function(data) { 
	$scope.user = DrupalAuthenticationService.getCurrentUser(); 
};
notificationChannel.onCurrentUserUpdated($scope, onCurrentUserUpdatedHandler);

But the event listening works only if i’m on this page. Normally it should work all the time…
I disabled the view cach globally in my app.js .config

 $ionicConfigProvider.views.maxCache(0);

and allso disabled the caching directly on the state

.state('app.authed-tabs.profile', {
	        url : "/profile",
	        cache : false,
	        views : {
	          'profile-tab' : {
	            templateUrl : "app/components/authed-tabs/profile/profile.html",
	            controller  : 'authedTabProfileCtrl'
	          }
	        },
	      })

I know i can load userdata from service on state resolve like i do now, but it’s not what i want!!!
In previous versions of ionic all work fine with this…
:sob::sob::sob:


#2

Does anybody have experience with events in hidden screens?


#3

Why not listening to event in app run and update rootscope or even better update localstorage and on beforeEnter profile page get value from localstorage?


#4

I have already some listening in app run, but yes this could be a way.
Anyway, do you know is it possible to listen on events in hidden views?

Thx


#5

Sorry I don’t know. Never tried it


#6

I’ve got the same error.


#7

hey @vlikin,
what is the purpose you need this functionality for?


#8

The controller, scope variable is not changed when the service variable is changed.

<ion-item ui-sref="car.statistics({car_uuid: activeCar.uuid})" ng-click="toggleLeft()">{{ 'Car statistics' }}</ion-item>

.controller('AppCtrl', function($scope, $ionicSideMenuDelegate, $state, Cars, alexData) {
  $scope.activeCar = Cars.getActive();

#9

If you mean if the cars service variable change then update controller activeCar you have to do this over an event.
You code is just executed the first time you app lounges (view caching).
So you have to implement eventing in you servicev and in your controller you have to listen to this event.

Did i understand you right?


#10

Yes, you are right. I started ro use $broadcast, $on. I had thought that $scope variables should be update automaticaly.


#11

Cool, so hopefully you were able to solve it. :smile:


#12

Is this issue solved? Because I used this a lot without problems. I have a service for http calls. The service sends a message thru a websocket to a websocket server. The server copies this message to all connected app users. Apps receive this message. OnReceive the apps emits an event to (of course not active controllers) to let them know an other app user has changed or inserted some data. The controller listened to event sends a http request to sync the data table. Works like a charm.


#13

hy @pcr,
it’s not solved yet.

I have a listCTRL. the list has option buttons. if i click edit a new page is viewd where i can edit this data.
on save a update event get fired. and in my listCTRL and in my editCTRL i listen to tihs events.

but just the current viewed CTRL (in my case the editCTRL) console.logs the event…


#14

How did you code the event??
How did you code the listeners??

Show me some code…


#15

i use a channel (interface like) for listen and publich events:

NodeResourceModules.service(‘NodeResourceChannel’, [’$rootScope’, ‘NodeResourceConfig’, function ($rootScope, NodeResourceConfig) {

    var publishNodeRetrieveConfirmed = function (node) {
        $rootScope.$broadcast(NodeResourceConfig.node_retrieveConfirmed, {node: node});
    };

    var onNodeRetrieveConfirmed = function($scope, handler) {
    	$scope.$on(NodeResourceConfig.node_retrieveConfirmed, function(event, args) {
	    handler(args.node);
	   });	
    };
   
 return {	   
	   publishNodeRetrieveConfirmed		: publishNodeRetrieveConfirmed,
	   onNodeRetrieveConfirmed			: onNodeRetrieveConfirmed,
	   publishNodeRetrieveFailed		: publishNodeRetrieveFailed,
	   onNodeRetrieveFailed 			: onNodeRetrieveFailed
}
}]);

i fire in the service like this:

NodeResourceModules.service('NodeResource', [ 'drupalApiConfig',  'NodeResourceConfig', 'NodeResourceChannel', '$http', '$q', function(drupalApiConfig,    NodeResourceConfig,   NodeResourceChannel,   $http,   $q) {
	
var retrieve = function(nid){

		var retrievePath = drupalApiConfig.drupal_instance + drupalApiConfig.api_endpoint + NodeResourceConfig.resourcePath + '/' + nid,
			defer = $q.defer(),
			requestConfig = {
				method :'GET',
				url : retrievePath
			},
			errors = [];
		
		if(!nid) { errors.push('Param nid is required.'); }
		
		if(errors.length != 0) {
			NodeResourceChannel.publishNodeRetrieveFailed(errors);
			defer.reject(errors); 
			return defer.promise;
		}
		
		
		$http(requestConfig)
		.success(function(data, status, headers, config){
				NodeResourceChannel.publishNodeRetrieveConfirmed(data);
				defer.resolve(data);
		})
		.error(function(data, status, headers, config){
				NodeResourceChannel.publishNodeRetrieveFailed(data);
				defer.reject(data);
		});
	
		return defer.promise;

	};

return {
		retrieve 	: retrieve,
	}
   }]);

and i listen in controler like this:

 NodeResourceChannel.onNodeRetrieveConfirmed($scope, function(node) { 
    console.log('in NodeListCtrl onNodeRetrieveConfirmed'); 
});

#16

the notification channel is described in detail here: http://codingsmackdown.tv/blog/2013/04/29/hailing-all-frequencies-communicating-in-angularjs-with-the-pubsub-design-pattern/


#17

but i guess even without this channel my problen is still there


#18
/*
 * This is how I generate an event
 * From an arbitrary controller or factory
 * You need $rootscope as a dependency in this controller or factory
 */

	$rootScope.$emit('syncUser', {
	    message: 'user syncdown SUCCESS'
	});

/*
 * This is how a controller is listen to the event
 * You need $rootscope as a dependency in this controller
 */
	var event3 = $rootScope.$on('syncUser', function(event, args) {
console.error('UserCtrl syncUser event: ', args.message);
		updateUserList();
	});
	$scope.$on('$destroy', event3);

#19

Sry for the late answer!

The thing is, if a ui-view holds the state of the controller and it is not activated (visible), it is also not in the digest loop. Therfore it will not realize the changes.

I stored the “event feeded” data in a sperate service and pull them if my view gets activated.

@pcr compared your rootscope emit eventing with rootscope broadcast and scope watch.

Rootscope emit is the fastest one. So i combined this with the channel logic.

I prepared some slides of this for one of my talks here
and the channel is here