2

I have a directive to do 2 things: (i) it manages the visualization of some tabs in HTML, (ii) it $watches the value of the object myObj in session storage and saves this object in a variable called myData. Here there is the code:

.directive('panelManager', function(){
    return {
        restrict: 'E',
        templateUrl: 'foo.html',

        controller: ['$scope', '$window',  function($scope, $window) {
            pn = this;
            pn.tab = 1; // init

            this.selectTab = function(setTab) {
                pn.tab = setTab;
            };

            this.isSelected = function(checkTab) {
                return pn.tab === checkTab;
            };

            $scope.$watch(function () {
                return $window.sessionStorage.getItem('myObj');
            }, function (value) {
                pn.myData = JSON.parse(value);
            });
        }],
        controllerAs: 'panels'
    };
})

I have a controller to call a WS passing a property foo of the aforementioned myData, every time it changes. Here it is:

.controller('MyDataController', ['$http', function($http) {

    pdc = this;
    pdc.myResultset = [];

    pdc.getDetails = function(val) {
        return $http.get("myUrl"+val+"/").then(function(response){
              pdc.myResultset= response.data;
        });
    };
}]);

Is there a way to trigger getDetails in that controller and to pass val = MyData.foo to it every time myData changes value? In this way, I could store in myResultset the current resultset of the WS and assign it to local scope.

1
  • One option is to put myData on root scope and then: 1. you can still access it from directive 2. You can watch changes in MyDataController Commented Jul 20, 2015 at 10:38

1 Answer 1

2

You can emit from your directive, but you need the $rootScope in the associated controller. So the declaration becomes:

controller: ['$rootScope', '$scope', '$window',  function($rootScope, $scope, $window) {

Then, you could do something like this:

$scope.$watch(function () {
    return $window.sessionStorage.getItem('myObj');
}, function (value) {
    pn.myData = JSON.parse(value);
    $rootScope.$broadcast('valueChanged', pn.myData);
});

And in your controller:

.controller('MyDataController', ['$http', '$scope', function($http, $scope) {

    pdc = this;
    pdc.myResultset = [];

    pdc.getDetails = function(val) {
        return $http.get("myUrl"+val+"/").then(function(response){
            pdc.myResultset= response.data;
        });
    };

    $scope.$on('valueChanged', function(event, data) {
        pdc.getDetails(data.foo); //pass data.foo to the function
    });
}]);
Sign up to request clarification or add additional context in comments.

4 Comments

Perfect, very cool! PS: If I had to re-use this strategy inside more controllers, could I insert $scope.on(...); in a factory? PPS: missing $ before broadcast and before on
Thanks for you feedback :) Of course you can ! Take a look at the following link: stackoverflow.com/a/16492065/4693496.
You are welcome! : ) Another interesting thing for readers: at the very first load myData is null and no valueChanged should happen, but for some reason pdc.getDetails(...) inside $scope.on(...); triggers in console this error: Cannot read property 'foo' of null

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.