How do you trigger a reload in angular-masonry?

余生长醉 提交于 2019-12-03 14:21:57

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.

SebastianRiemer

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

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');
    }
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!