2014-12-22 5 views
6

Sto cercando di ottenere l'offset e l'altezza delle voci di elenco. Una volta che ho quelle, chiamo una funzione su una direttiva genitore. Alla fine, questi saranno gli elementi di transizione dentro e fuori quando entrano in vista.Come ottenere i valori di altezza e offset corretti di un elemento quando si utilizza ng-repeat?

Problema: A causa della ng-repeat (non so perché), e el[0].offsetheightel[0].getBoundingClientRect().top; valori sono più o meno casuali; a meno che non completi un $timeout intorno alla logica. Penso che questo sia dovuto al fatto che gli stili hanno tempo per il rendering?

Domanda: come posso ottenere compensato un accurato ed altezza w/o avvolgendo un $timeout o utilizzando un $watch.

HTML:

<dt spyed ng-repeat="exp in experiences"> 
... 
</dt> 

JS:

app.directive('spyed', function() { 
    return { 
     require: '^scrollSpyer', 
     link: function(scope, el, attrs, ctrl) { 
      // this value is mostly random after the $first ng-repeat item 
      var offset = el[0].getBoundingClientRect().top; 
      // this value is also mostly randome after the $first ng-repeat item 
      var theHeight = el[0].offsetHeight; 
      // this fires the expMapper on parent directive. 
      ctrl.expMapper(offset, theHeight); 
     } 
    }; 
}); 

Sidenote sul perché non utilizzare un osservatore: La ragione per cui non voglio usare un osservatore è che sono spingendo questi valori alla raccolta nella direttiva genitore. Non voglio continuare a reimpostare l'array che dovrò fare se continua a sparare ctrl.expMapper() ogni 2 vie vincolante.

direttiva sulle società madri:

app.directive('scrollSpyer', function ($window, Experiences) { 
    return { 
     controller: function($scope){ 
      $scope.experiences = []; 
      this.expMapper = function(offset, height) { 
       $scope.experiences.push({'offset': offset, 'height': height, 'inView': false}); 
      }; 
     }, 
     link: function(scope) { 
      var i = 0; 
      angular.element($window).bind('scroll', function() { 

       if(i < scope.experiences.length) { 
        if (this.pageYOffset >= scope.experiences[i].offset) { 
         Experiences.status.push(scope.experiences[i]); 
         i++; 
        } else { 
         console.log('middle'); 
        } 
       } 

       scope.$apply(); 
      }); 
     } 
    }; 
}); 
+1

Per quanto riguarda le mie ricerche, è necessario un timeout di $ con 0 secondi per iniziare qualsiasi calcolo delle dimensioni dell'elemento dom dopo che l'ambito e il DOM sono stati aggiornati. –

+0

Posso suggerire di spostare la logica che chiamerà ctrl.expMapper nell'elemento ng-repeat in modo che sia: 'dt -> wrapper (direttiva spyed qui) -> item-content.' – BotanMan

+1

Dai un'occhiata a [questo violino] (http://jsfiddle.net/4089at1L/). Ho provato a creare questo, ma tutto sembra a posto per me. I valori non sembrano affatto casuali. Fammi sapere se mi manca qualcosa qui? – scniro

risposta

0

Ne fanno una funzione in $ portata:

$scope.getOffsets = function() { 
    //Do your logic here 
}; 

Nota questa piccola differenza:

<dt spyed ng-repeat="exp in experiences" ng-init="$last ? getOffsets(): ''"> 
    ... 
</dt> 

ng-init in base alla condizione di controllo Ultimo indice lo farà avvenire senza timeout

Problemi correlati