williamsowen
williamsowen

Reputation: 497

Updating $scope from another controller using a directive

I have a page which lists numerous types of 'tiles' (<div>'s) in a main content area and a header which has a list of links which acts as filters.

E.g. In the header area, click the 'pdf' filter link - only tiles which have ng-show="showFiles['pdf'] will be shown. If 'video' is clicked, tiles with ng-show="showFiles['video'] will show and so on..

The header template is controlled by hdrController and the tiles by pageController.

Initially, when the view loads the $scope variable showFiles in pageController receives an object from a service Tweaks which sets all items to true (thus showing all tiles at start up):

testApp.controller('pageController', ['$scope', 'Tweaks', function($scope, Tweaks){
  $scope.showFiles = Tweaks.tagFilters('all');
}]);

testApp.factory('Tweaks', function(){
  var tweaksFactory = {};
  var obj = {};

  tweaksFactory.tagFilters = function(filter) {
    if(filter == 'all') {
      obj = {
        'video' : true,
        'pdf' : true,
        'doc' : true
      };
    } else {
      obj = {
        'video' : false,
        'pdf' : false,
        'doc' : false
      };
    }
    return obj;
  };
  return tweaksFactory;
});

Question: When clicking the filter links, a directive is applied which detects clicks - this then needs to update $scope.showFiles to show only tiles which are of the specific filter type.

See Plunkr - The $scope of pageController which contains the showFiles object doesn't update, so the changes aren't reflected.

Can someone offer any suggestions? I'm new to Angular - is this approach the best way to achieve the result?

Upvotes: 0

Views: 80

Answers (2)

Michael
Michael

Reputation: 3104

You allways create a new 'obj' - so the reference in the controller won't be updated. Anyway you should always access the data/status through service functions. plnkr

  testApp.factory('Tweaks', function(){
  var tweaksFactory = {};
  var obj = {};

  tweaksFactory.tagFilters = function(filter) {
    if(filter == 'all') {
      obj = {
        'video' : true,
        'pdf' : true,
        'doc' : true
      };
    } else {
      obj = {
        'video' : false,
        'pdf' : false,
        'doc' : false
      };
      obj[filter] = true;
    }
    console.log('alter the object - so it reflects in the scope');
    console.log(obj);
    return obj;
  };
  tweaksFactory.show = function(type) {
    console.log(obj, type);
    return obj[type];
  };
  return tweaksFactory;
});

Upvotes: 1

Aleksandar Gajic
Aleksandar Gajic

Reputation: 1359

communication with two or more controllers is done with services and events, you can do it with adding new service for broadcasting messages

testApp.factory('mySharedService', function($rootScope) {
    var sharedService = {};

    sharedService.prepForBroadcast = function(msg) {
        $rootScope.$broadcast('handleBroadcast', msg);
    };

    return sharedService;
});

You can see your code updated using this service to allow directive to communicate with controller: http://plnkr.co/edit/M3RECJmZa64cxKtpWeHO?p=info

Upvotes: 1

Related Questions