与AngularJS砌筑 [英] Masonry with AngularJS

查看:120
本文介绍了与AngularJS砌筑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个艺术画廊的应用程序。

I am developing an "art gallery" app.

随意拉下 在github 源和玩它

Feel free to pull down the source on github and play around with it.

Plunker完整源。

Plunker with full source.

目前的工作围绕获取砌体播放用角很好的:

.directive("masonry", function($parse) {
  return {
    restrict: 'AC',
    link: function (scope, elem, attrs) {
      elem.masonry({ itemSelector: '.masonry-brick'});
    }
  };     
})
.directive('masonryBrick', function ($compile) {
  return {
    restrict: 'AC',
    link: function (scope, elem, attrs) {
      scope.$watch('$index',function(v){
        elem.imagesLoaded(function () {
          elem.parents('.masonry').masonry('reload');
        });
      });
    }
  };    
});

这不能很好地工作,因为:

This doesn't work well because:


  • 作为内容的增长,所以没有整个容器上触发时重装的开销。

重新加载功能:


  • 追加的物品,而重新排列容器中的每一个项目。

  • 是否作为触发重载物品时,被过滤掉的结果集的工作。

  • Does not "append" items, rather re-arranges every item in the container.
  • Does work for triggering a reload when items are filtered out of a result set.

在用我给的链接上面的应用程序的背景下,这个问题就变得非常容易复制。

我要寻找这将使用指令杠杆的解决方案:

.masonry('附加',ELEM) .masonry('prepended',ELEM)

而不是执行 .masonry('重装')每次

.masonry('重装')时的元素从结果集中删除了。

.masonry('reload') for when elements are removed from result set.

该项目已更新为使用下面的工作方案。

抢在源 GitHub的

Grab the source on GitHub

请参阅 Plunker

See a working version on Plunker

推荐答案

我一直在这了一点,@ ganaraj的回答玩耍是pretty整洁。如果你坚持一个 $ element.masonry('调整'); 在他控制的 appendBrick 方法和账户
然后将图像加载它看起来像它的工作原理。

I've been playing around with this a bit more and @ganaraj's answer is pretty neat. If you stick a $element.masonry('resize'); in his controller's appendBrick method and account for the images loading then it looks like it works.

下面是一个plunker叉它: http://plnkr.co/edit/8t41rRnLYfhOF9oAfSUA

Here's a plunker fork with it in: http://plnkr.co/edit/8t41rRnLYfhOF9oAfSUA

究其原因,这是必要的,因为当砖石被初始化的元素或容器大小,而在这一点上,我们还没有得到任何砖头所以它默认为一列只计算列数。

The reason this is necessary is because the number of columns is only calculated when masonry is initialized on the element or the container is resized and at this point we haven't got any bricks so it defaults to a single column.

如果你不希望使用调整的方法(我不认为它的​​记录),那么你可以只调用$ element.masonry(),但会导致重新布局,所以你会希望只把它添加的第一个砖时。

If you don't want to use the 'resize' method (I don't think it's documented) then you could just call $element.masonry() but that causes a re-layout so you'd want to only call it when the first brick is added.

编辑:我已经更新上面只调用plunker 调整在列表上方的增长0长度,只有一个办重装当多个砖头在同一$被删除消化周期。

I've updated the plunker above to only call resize when the list grows above 0 length and to do only one "reload" when multiple bricks are removed in the same $digest cycle.

指令code是:

angular.module('myApp.directives', [])
  .directive("masonry", function($parse, $timeout) {
    return {
      restrict: 'AC',
      link: function (scope, elem, attrs) {
        elem.masonry({ itemSelector: '.masonry-brick'});
        // Opitonal Params, delimited in class name like:
        // class="masonry:70;"
        //elem.masonry({ itemSelector: '.masonry-item', columnWidth: 140, gutterWidth: $parse(attrs.masonry)(scope) });
      },
      controller : function($scope,$element){
          var bricks = [];
          this.appendBrick = function(child, brickId, waitForImage){
            function addBrick() {
              $element.masonry('appended', child, true);

              // If we don't have any bricks then we're going to want to 
              // resize when we add one.
              if (bricks.length === 0) {
                // Timeout here to allow for a potential
                // masonary timeout when appending (when animating
                // from the bottom)
                $timeout(function(){
                  $element.masonry('resize');  
                }, 2);  
              }

              // Store the brick id
              var index = bricks.indexOf(brickId);
              if (index === -1) {
                bricks.push(brickId);
              }
            }

            if (waitForImage) {
              child.imagesLoaded(addBrick);      
            } else {
              addBrick();
            }
          };

          // Removed bricks - we only want to call masonry.reload() once
          // if a whole batch of bricks have been removed though so push this
          // async.
          var willReload = false;
          function hasRemovedBrick() {
            if (!willReload) {
              willReload = true;
              $scope.$evalAsync(function(){
                willReload = false;
                $element.masonry("reload");
              });
            }
          }

          this.removeBrick = function(brickId){
              hasRemovedBrick();
              var index = bricks.indexOf(brickId);
              if (index != -1) {
                bricks.splice(index,1);
              }
          };
      }
    };     
  })
  .directive('masonryBrick', function ($compile) {
    return {
      restrict: 'AC',
      require : '^masonry',
      link: function (scope, elem, attrs, MasonryCtrl) {

      elem.imagesLoaded(function () {
        MasonryCtrl.appendBrick(elem, scope.$id, true);
      });

      scope.$on("$destroy",function(){
          MasonryCtrl.removeBrick(scope.$id);
      }); 
    }
  };
});

这篇关于与AngularJS砌筑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆