Search code examples
angularjsjquery-masonryangularjs-directive

Jquery Masonry with AngularJS


in my project i try to implement jquery masonry. but its getting working. i try googling but found some post. but i tried it its not working.

my directive code is

shout.directive("shoutList", function($timeout) {
    return  {
        restrict : 'E',

        replace : true,

        templateUrl : 'views/shout/shout-list.html',

        scope : {
            shouts : "="
        },

        //require : "ShoutController",

        controller : function($scope)   {
            $scope.deleteShout = function() {
                console.log('shout deleted');
            }
        },

        link : function(scope, element, attr)   {
            scope.$watch('shouts', function()   {
                // console.log("changing......");
                // scope.$evalAsync(
                    document.getElementById("shout-content-holder").masonry({
                        itemSelector: '.shout'
                    })
                // );
            });
        }
    }
});

directive template is

<div id="shout-content-holder">
    <div class="shout" ng-repeat="shout in shouts">
        <p>{{shout.message}}</p>
        <img src="media/images/delete.png" width="32" height="32" ng-click="deleteShout()"/>
    </div>
</div>

i load the shouts from a webservice. please help me to make this work...


Solution

  • Putting what I mentioned in comment as an answer. This could actually be done using a template rather than using .append() , it would be cleaner. What you'd need is a template to contain a list of columns and ng-repeat, should work just as well, but you'd have to wait for the first item to get inserted before you calculate where to insert the second item; hence the use of .append() here.

    .directive('columns', function(){
      return {
        restrict: 'E',
        scope: {
            itemList: '=', // a list of items
            colCount: "@"  // number of columns
        },
        link: function(scope, elm, attrs) {
          //console.log(scope.itemList);
          var numCols = parseInt(scope.colCount);
          var colsArr = [];
          for(var i=0; i< numCols; i++){
            colsArr.push(angular.element("<div class='column' style='width:"+(100/numCols -.5)+"%' >Col "+(i+1)+"</div>"));
             elm.append(colsArr[i]); 
          }
    
          angular.forEach(scope.itemList, function(value, key){
            var item = angular.element("<div class='item' style='height:"+value.height+"px; background:"+'#'+Math.floor(Math.random()*16777215).toString(16)+"'>"+value.value+"</div>");
            var smallestColumn = getSmallestColumn();
            angular.element(smallestColumn).append(item);
          });
          
          function getSmallestColumn(){
            var smallestHeight = colsArr[0][0].offsetHeight;
            var smallestColumn = colsArr[0][0]; 
            angular.forEach(colsArr, function(column, key){ 
              if(column[0].offsetHeight < smallestHeight){
                smallestHeight = column[0].offsetHeight;
                smallestColumn = colsArr[key]; 
              }
            }); 
            return smallestColumn;
          }
        }
      };
    });
    

    Runnable example