2013-04-14 3 views
5

jQueryのQuicksand pluginをAngularで実装する方法はありますか?実装があるかもしれませんが、見つけられないようです。AngularJS Quicksand

クイックサンドがリストを取得して新しいリストをパラメータとして受け取るが、Angularのデータを再レンダリングする方法では、どうやってそれを行うのかわからないので、おそらくそれを行う戦略が役に立つだろう。

+0

他のDOM操作プラグインと同じように、角度指令内で初期化する必要があります。もし、angleが 'ng-repeat'のような' LI'要素を作成するなら、 '$ timeout'にコードをラップしてください。 – charlietfl

+0

@charlietfl、何? – arg20

+1

「what」とは何ですか? – charlietfl

答えて

8

私は石工ディレクティブ+の入力/アニメーションを残すためNG-アニメーションを使用して似たような実装、ここでCSSアニメーションは(クロムベンダー接頭辞CSS付き)のみのデモです:

http://jsfiddle.net/g/3SH7a/

ディレクティブ:

angular.module('app', []) 
.directive("masonry", function() { 
    var NGREPEAT_SOURCE_RE = '<!-- ngRepeat: ((.*) in ((.*?)(track by (.*))?)) -->'; 
    return { 
     compile: function(element, attrs) { 
      // auto add animation to brick element 
      var animation = attrs.ngAnimate || "'masonry'"; 
      var $brick = element.children(); 
      $brick.attr("ng-animate", animation); 

      // generate item selector (exclude leaving items) 
      var type = $brick.prop('tagName'); 
      var itemSelector = type+":not([class$='-leave-active'])"; 

      return function (scope, element, attrs) { 
       var options = angular.extend({ 
        itemSelector: itemSelector 
       }, attrs.masonry); 

       // try to infer model from ngRepeat 
       if (!options.model) { 
        var ngRepeatMatch = element.html().match(NGREPEAT_SOURCE_RE); 
        if (ngRepeatMatch) { 
         options.model = ngRepeatMatch[4]; 
        } 
       } 

       // initial animation 
       element.addClass('masonry'); 

       // Wait inside directives to render 
       setTimeout(function() { 
        element.masonry(options); 

        element.on("$destroy", function() { 
         element.masonry('destroy') 
        }); 

        if (options.model) { 
         scope.$apply(function() { 
          scope.$watchCollection(options.model, function (_new, _old) { 
           if(_new == _old) return; 

           // Wait inside directives to render 
           setTimeout(function() { 
            element.masonry("reload"); 
           }); 
          }); 
         }); 
        } 
       }); 
      }; 
     } 
    }; 
}) 
+0

素晴らしいディレクティブ! – arg20

+0

それはかなり滑らかです。私はより複雑な例で作業しています。そこにLIのコンテナ(これはLIです)があり、アニメーションがすべての子孫に適用されるという問題があります。 var itemSelector = 'masonry>' + type + ":not([class $ = ' - leave-active'])を使用しないで、 '-leave-active']) ";' – Kywillis

0

これを行うには、directiveを追加する必要があります。

はそうちょうどjQueryを使って、あなたが持っていると思います:あなたができる

角度で

JS

$('#source').quicksand($('#destination li')); 

HTML

<ul id="source"> 
    <li data-id="iphone">iOS</li> 
    <li data-id="android">Android</li> 
    <li data-id="winmo">Windows Phone 7</li> 
</ul> 

<ul id="destination" class="hidden"> 
    <li data-id="macosx">Mac OS X</li> 
    <li data-id="macos9">Mac OS 9</li> 
    <li data-id="iphone">iOS</li> 
</ul> 

を:

JS

yourApp.directive('jqQuicksand', function(){ 
    var linkFn = function(scope,element,attrs){ 
     // element here = $(this) 
     // bind your plugin or events (click, hover etc.) here 
     element.quicksand($(attrs.jqQuicksand)); 
    } 

    return { 
     restrict:'A', 
     scope: {}, 
     link: linkFn 
    } 
}); 

HTML

<ul data-jq-quicksand="#destination li" id="source"> 
    <li data-id="iphone">iOS</li> 
    <li data-id="android">Android</li> 
    <li data-id="winmo">Windows Phone 7</li> 
</ul> 

<ul id="destination" class="hidden"> 
    <li data-id="macosx">Mac OS X</li> 
    <li data-id="macos9">Mac OS 9</li> 
    <li data-id="iphone">iOS</li> 
</ul> 

注、これはテストされていないが、OKである必要があります。