3

how to tell angularjs to stop watching an expired data object and force controllers to restart to look at a new model instance ?

    var ang = angular.module('ang', []);

    ang.controller('userCtrl', function($scope) {
        $scope.userData = myProject.getUserData(); // an OOP js data tree
    } 

    angular.bootstrap(document, ['ang']);

    // ... 

    myProject.reloadUserData(); // userData now a new instance

Angular works perfectly until I destroy the user data object to create a new data object instance.

How to tell angular to stop watching the old user data and start looking the new ? Basically I want to restart angular or the controllers.

John
  • 33
  • 1
  • 4
  • what is triggering the myProject.reloadUserData() method? Angular has mechanisms for triggering the update without breaking down the controller or restarting angular, but how the new data is getting to the controller is important. – Steve Mitcham Jan 16 '15 at 20:50
  • what is myProject? 3rd party data should be injected using a service. than u can watch the object change from controller http://stackoverflow.com/questions/20667474/angularjs-trigger-and-watch-object-value-change-in-service-from-controller – micha Jan 16 '15 at 21:06
  • reloadUserData only creates a new instance of a complex OOP data tree object used by all the application. The getUserData is just an accessor to the current instance. – John Jan 16 '15 at 21:08
  • It's very simplifyed here but myProject is a big web application that uses angular to display/update some views. It's not a 100% angular application. – John Jan 16 '15 at 21:11

1 Answers1

2

There's no need to restart your angular app just because the model updated. Not only is that round-about, but you'll have to take the performance hit of re-compiling the DOM.

Instead, I would suggest you create a service to handle the synchronization.

ang.factory('userService', function ($rootScope) {
    var userService = {
        // We'll initialize this in a moment
        data: undefined,

        // Method to refresh the data property
        refresh: function () {
            userService.data = myProject.getUserData();
        }
    };

    userService.refresh();

    return userService;
});

Now, in your controller, you'll use this service rather than the global myProject object.

ang.controller('userCtrl', function($scope, userService) {
    $scope.user = userService; // Bind to {{user.data}} in your templates
});

Finally, whenever you call myProject.reloadUserData(), you have to refresh the userService object.

$(document.body).injector().invoke(function (userService) {
    userService.refresh();
});

You may just want to add that to the method.

Chris Bouchard
  • 806
  • 7
  • 12
  • It works, thank you Chris :) But I'm a little surprised that you need to encapsulate the data source in a service to do that. So Angularjs has no method to dynamically change the data binding in a controller ? – John Jan 16 '15 at 23:02
  • You could do this same thing directly with the controller, but that's not really the place for it. Heck, you could just put it all in `$rootScope` and update it that way. Using a service *allows* you to encapsulate the refresh logic. – Chris Bouchard Jan 17 '15 at 04:09