2013-04-14 9 views
5

Esiste un modo per implementare jQuery Quicksand plugin in Angolare? Forse c'è un'implementazione ma non riesco a trovarla.AngularJS Quicksand

Forse una strategia per farlo mi aiuterebbe perché le sabbie mobili prendono una lista e quindi riceve come parametro la nuova lista, ma con il modo di ri-rendering dei dati di Angular non ho idea di come farlo.

+0

come con qualsiasi altro plugin di manipolazione DOM, è necessario inizializzarlo all'interno di una direttiva angolare. Avvolgi il tuo codice in '$ timeout' se angular creerà gli elementi' LI' come con 'ng-repeat' – charlietfl

+0

@charlietfl, cosa? – arg20

+1

cosa è 'cosa? ' – charlietfl

risposta

8

ho implementato qualcosa di simile utilizzando una muratura direttiva + ng-animate per entrare/uscire animazioni, ecco un'animazione CSS solo demo (con bicromato di potassio fornitore CSS prefisso):

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

La direttiva:

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

Direttiva sorprendente! – arg20

+0

Questo è abbastanza lucido. Sto lavorando con un esempio più complesso in cui ci sono LI all'interno del contenitore (che è anche un LI) e c'è un problema con l'animazione applicata a tutti i discendenti. La mia correzione era di cambiare 'var itemSelector = type +": not ([class $ = '- leave-active']) ";' a 'var itemSelector = '.masonry>' + type +": not ([class $ = '-Lasciare-attivo']) ";' – Kywillis

0

Per aggiungere questo è necessario aggiungere un directive.

Quindi, con solo jQuery, si avrebbe:

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> 

Con angolare si potrebbe fare:

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> 

Nota, questo non è testato, ma dovrebbe essere ok.