Jason
Jason

Reputation: 1141

bind data between controllers in Angular

Not sure if I am doing this correctly. I have two controllers. One pulls all posts. the other gives me the count of all the posts in the trash can. It currently works but only one way. If I undo a post from the trash can and put it back into the population the count changes to reflect the new number but if I send a post to the trash the count does not update.

Here is my Service:

app.service('sharedProperties', function () {

});

Here is my first controller: (This controller supplies all the posts and has the trash function)

app.controller('postsCtrl', function ($scope, $log, $http, $timeout, Data, $uibModal, sharedProperties) {
    Data.get('posts').then(function(data){
        $scope.posts = data.data;
        $scope.currentPage = 1; //current page
        $scope.filteredItems = $scope.posts.length; //Initially for no filter  
        $scope.totalItems = $scope.posts.length;
        $scope.list_pages = [
                {
                    id: '5',
                    name: '5'
                }, {
                    id: '10',
                    name: '10'
                }, {
                    id: '20',
                    name: '20'
                }, {
                    id: '50',
                    name: '50'
                }, {
                    id: '100',
                    name: '100'
                }
            ];
        $scope.maxSize = 5;
    });
    $scope.setPage = function(pageNo) {
        $scope.currentPage = pageNo;
    };
    $scope.filter = function() {
        $timeout(function() { 
            $scope.filteredItems = $scope.filtered.length;
        }, 10);
    };
    $scope.sort_by = function(predicate) {
        $scope.predicate = predicate;
        $scope.reverse = !$scope.reverse;
    };
    $scope.changePostStatus = function(post){
        post.approved = (post.approved=="1" ? "0" : "1");
        Data.put("posts/"+post.id,{approved:post.approved}).then(function (result) {
            Data.toast2(result);
        });
    };
    $scope.changePostAnnounce = function(post){
        post.announce = (post.announce=="1" ? "0" : "1");
        Data.put("posts/"+post.id,{announce:post.announce}).then(function (result) {
            Data.toast2(result);
        });
    };
    $scope.trashPost = function(post){
        if(confirm("Are you sure to remove the post")){
            Data.delete("posts/"+post.id).then(function(result){
                $scope.posts = _.without($scope.posts, _.findWhere($scope.posts, {id:post.id}));
                $scope.totalItems = $scope.posts.length;
                Data.toast(result);
            });
        }
    };
    $scope.open = function (p,size) {
        var modalInstance = $uibModal.open({
          templateUrl: 'views/postsEdit.html',
          controller: 'postsEditCtrl',
          size: size,
          resolve: {
            item: function () {
              return p;
            }
          }
        });
        modalInstance.result.then(function(selectedObject) {
            if(selectedObject.save == "insert"){
                $scope.posts.push(selectedObject);
                $scope.posts = $filter('orderBy')($scope.posts, 'id', 'reverse');
            }else if(selectedObject.save == "update"){
                p.title = selectedObject.title;
                // p.price = selectedObject.price;
                // p.stock = selectedObject.stock;
                // p.packing = selectedObject.packing;
            }
        });
    };

});

Here is my second controller: (this controller counts the posts in the trashcan)

app.controller('postsTrashCtrl', function ($scope, $log, $http, $timeout, Data, sharedProperties) {
    Data.get('trash').then(function(data){
        $scope.trash = data.data;
        $scope.totalTrashItems = $scope.trash.length;
    });

});

In controller 1 the trashPost function is where I am trying to update totalTrashItems from controller 2

I know it is something small that I am missing.

UPDATE

the HTML that has the controller and variable:

<div class="container">
        <div class="row" align="center">
            <div class="stats" ng-controller="postsTrashCtrl"><i class="fa fa-thumb-tack"></i> Total Posts (<span class="attendStat">{{ totalItems }}</span>)<span class="seperator">&nbsp;&nbsp;|&nbsp;&nbsp;</span><i class="fa fa-trash-o"></i> <a href="#/trash" id="trashCan" class="trashCan">Trash</a> (<span class="attendStat">{{totalTrashItems}}</span>)</div>
        </div>

Upvotes: 0

Views: 82

Answers (1)

Ji_in_coding
Ji_in_coding

Reputation: 1701

I saw that you have an empty service there.

without looking too deep into your current code. My solution for inter-controller communication for this context would be to $broadcast("customEventName") on Post, Trash and UnTrash events.

and your PostController and TrashPostController will subscribe to these broadcasted events using $on("customEventName", function(){ })

All the posting and trashing of data, and even communication with server is to be maintained using one PostTrackingService. In this case your controller will simply call the service if it need to perform anything with posting and tracking.

I know this is a bit lengthy to read through. I would suggest first look at the html, then get of a light of how those controllers work, and finally look at how the service is defined. If you apply this pattern to your code. your problem will be resolved.

Here is the code. You can also play with it on JSFiddle

<script src="https://code.angularjs.org/1.4.9/angular.min.js"></script>
<div ng-app="myApp">

  <div ng-controller="PostController">
    {{postCount}}
    <button ng-click="post()">
      Post
    </button>
    <button ng-click="trash()">
      Trash
    </button>
  </div>

  <div ng-controller="TrashController">
    {{trashCount}}
    <button ng-click="untrash()">
      UnTrash
    </button>
  </div>

</div>

<script>

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

//----------------- Service to track all post changes ---------------
app.factory('PostTrackingService', function($rootScope) {
  var postCount = 10;
  var trashCount = 3;

  var _postTrackingService = {};

  _postTrackingService.getPostCount = function(){ return postCount};
  _postTrackingService.post = function(dataToPost){ 
    //do something with dataToPost

    postCount++;

    //broadcast a post event
    $rootScope.$broadcast("A custom POST event invented by me");
  };

  _postTrackingService.getTrashCount = function(){ return trashCount};
  _postTrackingService.trash = function(postId){
    //do something with postId

    trashCount++;
    postCount--;

    //broadcast a trash event
    $rootScope.$broadcast("A custom TRASH event invented by me");
  };

  _postTrackingService.untrash = function(postId){
    //do something with postId

    trashCount--;
    postCount++;

    //broadcast a trash event
    $rootScope.$broadcast("A custom UNTRASH event invented by me");
  };

  return _postTrackingService;
});



//----------------- Post Controller ---------------
app.controller("PostController", ["PostTrackingService", "$scope", "$rootScope", function(PostTrackingService, $scope, $rootScope){
    $scope.postCount = PostTrackingService.getPostCount();

  $rootScope.$on("A custom POST event invented by me", function(){
    $scope.postCount = PostTrackingService.getPostCount();
  });

  $rootScope.$on("A custom TRASH event invented by me", function(){
    $scope.postCount = PostTrackingService.getPostCount();
  });

  $rootScope.$on("A custom UNTRASH event invented by me", function(){
    $scope.postCount = PostTrackingService.getPostCount();
  });

  $scope.post = function(){
    PostTrackingService.post("some data to post to server");
  }

  $scope.trash = function(){
    PostTrackingService.trash("a post ID");
  }

}]);

//----------------- Trash Controller ---------------
app.controller("TrashController", ["PostTrackingService", "$scope", "$rootScope", function(PostTrackingService, $scope, $rootScope){
    $scope.trashCount = PostTrackingService.getTrashCount();

  $rootScope.$on("A custom TRASH event invented by me", function(){
    $scope.trashCount = PostTrackingService.getTrashCount();
  });

  $rootScope.$on("A custom UNTRASH event invented by me", function(){
    $scope.trashCount = PostTrackingService.getTrashCount();
  });

  $scope.untrash = function(){
    PostTrackingService.untrash("some post id");
    //make any calls to inform server
  }

}]);

</script>

Upvotes: 1

Related Questions