最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do you trigger a reload in angular-masonry? - Stack Overflow

programmeradmin0浏览0评论

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!

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!

Share Improve this question edited May 13, 2015 at 16:09 cristiano2lopes 3,4982 gold badges20 silver badges23 bronze badges asked May 17, 2014 at 10:27 John SmithJohn Smith 831 silver badge8 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 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.

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');
    }
});
发布评论

评论列表(0)

  1. 暂无评论