How do you trigger a reload in angular-masonry?
Asked Answered
A

3

6

I got Masonry to work in my AngularJS app using the angular-masonry directive but I want to be able to call a function or method in my controller that will trigger a reload of items in the container. I see in the source code (lines 101-104) there is a reload method but I'm not sure how to invoke that. Any ideas?

Thanks!

Addi answered 17/5, 2014 at 10:27 Comment(0)
J
19

In case it's of use to someone in the future, Passy watches for an event called masonry.reload.

So, you can issue this event and Passy should call 'layout' on the masonry element, e.g. call

$rootScope.$broadcast('masonry.reload');

In my case, I had some third-party javascript decorating my bricks, so I needed to repaint after that was done. For reason (I was not able to figure out why), I needed to wrap the event broadcast in a timeout, I think the Passy scheduler was eating up the event and not repainting. E.g. I did:

$timeout(function () {
   $rootScope.$broadcast('masonry.reload');
   }, 5000);

This way you don't have to modify Passy directly.

Jaques answered 18/10, 2014 at 13:52 Comment(1)
Although not documented it works. Thanks for the pointer. I didn't had to put the $timeout to make it work so you are right (that has something to do with your specific setup).Quaquaversal
T
0

I don't think you can trigger the reload() method directly, since it is part of the controller which is only visible within the directives.

You might either ...

A) trigger a reload directly of masonry via the element, jQuery-style

(see http://jsfiddle.net/riemersebastian/rUS9n/10/):

$scope.doReloadRelatively = function(e) {
    var $parent = $(e.currentTarget).parent().parent();
    $parent.masonry();
}

$scope.doReloadViaID = function() {
    $('#container').masonry();
}

B) or extend the directives yourself, i.e. add necessary watches on masonry-brick and call the reload() method within (depends on what use-case you have).

.directive('masonryBrick', function masonryBrickDirective() {
  return {
    restrict: 'AC',
    require: '^masonry',
    scope: true,
    link: {
      pre: function preLink(scope, element, attrs, ctrl) {
        var id = scope.$id, index;

        ctrl.appendBrick(element, id);
        element.on('$destroy', function () {
            console.log("masonryBrick > destroy")
          ctrl.removeBrick(id, element);
        });

        scope.$watch(function () {
            return element.height();
        },
        function (newValue, oldValue) {
            if (newValue != oldValue) {                    
                console.log("ctrl.scheduleMasonryOnce('layout');");
                ctrl.scheduleMasonryOnce('layout');
            }
        }
      );
      ...

In the code block above, I've simply added a watch on the element with the class 'masonry-brick' in order to trigger a reload of masonry whenever the elements' height changes.

I've created a jsFiddle for testing passys' angular-masonry myself, feel free to check it out!

http://jsfiddle.net/riemersebastian/rUS9n/10/

EDIT:

Just found a similar post on stackoverflow which could be another solution to this problem:

AngularJS Masonry for Dynamically changing heights

Tuft answered 28/7, 2014 at 14:34 Comment(0)
B
0

The answer from @SebastianRiemer helped me.

But for future persons that need help try instead use the following

scope.$watch(function () {
    return element.height();
},
function (newValue, oldValue) {
    if (newValue != oldValue) {
        ctrl.scheduleMasonryOnce('reloadItems');
        ctrl.scheduleMasonryOnce('layout');
    }
});
Bolitho answered 17/11, 2015 at 15:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.