2013-04-14 9 views
5

Gibt es eine Möglichkeit, jQuery Quicksand plugin in Angular zu implementieren? Vielleicht gibt es eine Implementierung, aber ich kann es nicht finden.AngularJS Quicksand

Vielleicht würde mir eine Strategie helfen, weil Quicksand eine Liste nimmt und dann als Parameter die neue Liste erhält, aber mit Angulars Art, Daten neu zu rendern, weiß ich nicht, wie ich das machen soll.

+0

wie bei jedem anderen DOM-Manipulations-Plugin, muss es innerhalb einer eckigen Anweisung initialisiert werden. Wickeln Sie Ihren Code in '$ timeout', wenn eckle die' LI' Elemente erzeugt, zB mit 'ng-repeat' – charlietfl

+0

@charlietfl, was? – arg20

+1

was ist 'was'? – charlietfl

Antwort

8

I umgesetzt etwas ähnlich ein gemauerten Richtlinie + ng-belebte Verwendung für Animationen geben/verlassen, hier ist eine CSS-Animation nur Demo (mit Chrom-Anbietern voran CSS):

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

Die Richtlinie:

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

Erstaunliche Anweisung! – arg20

+0

Das ist ziemlich glatt. Ich arbeite mit einem komplexeren Beispiel, in dem sich LI innerhalb des Containers befinden (der auch ein LI ist) und es gibt ein Problem mit der Animation, die auf alle Nachkommen angewendet wird. Meine Lösung war 'var itemSelector = type +" zu ändern: not ([class $ = '- leave-active']) ";' zu 'var itemSelector = '.maurryon>' + type +": not ([class $ = '-leave-active']) ";' – Kywillis

0

Sie müssen dazu einen directive hinzufügen.

mit nur jQuery So, dann würden Sie haben:

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> 

mit kantig Sie tun können:

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> 

Hinweis, dies ist nicht getestet, aber sollte in Ordnung sein.