2013-12-19 44 views
0

嗨我有一個工廠,從後端獲取數據。然後使用控制器處理該數據(如下所示),並使用ng-repeat將其注入到網頁中。由於系統的異步性質,當我嘗試操作窗口時遇到麻煩。例如,我需要使用window.scrollTo函數,但只有在數據完全處理後才能使用ng-repeat顯示在屏幕上。延遲數據檢索和顯示後的過程

正如你在這裏看到的,我試圖在控制器的早期使用承諾。但它不起作用:在屏幕上完成數據處理之前,始終處理window.scrollTo。我想我需要的是一種實際強制數據處理完成的方法,然後才處理window.scrollTo函數,但我看不出如何。

.controller('myCtrl', 
    function ($scope, prosFactory, fieldValues, $q) { 
     $scope.listpros = function() { 
      prosFactory.getPros() 
       .success(function(data, status) { 
        var defer = $q.defer(); 
        defer.promise 
         .then(function() { 
          $scope.prosItems = data; // pass data to ng repeat first       
          }) 
         .then(function() { 
          $window.scrollTo(0, 66); // then scroll 
          }); 
        defer.resolve(); 
       }).error(function(data, status) { 
        alert("error"); 
       } 
      ); 
     }; 

我試圖與scrollTo功能的2000超時,但由於網絡速度的變化,有時會耽誤滾動到多,或有時是不夠的。

回答

0

在這種情況下,承諾不會有太大幫助,因爲它沒有以任何方式連接到ng-repeat進程。但是,您可以使用自定義指令來處理最後一個項目時的事件$emit。您的控制器可以聽取該特定事件並根據您的需求對其做出反應。

This answer向您展示瞭如何實現這一目標,它甚至還帶有一個Plunker。

編輯:一般的方法來控制DOM創建

內AngularJS世界,DOM元素控制,在這種情況下的監督,通過指令。我上面鏈接的答案擴展了ng-repeat指令的行爲,但您可以對可能的任何DOM元素執行相同的操作。一個指令creation-emitter可能是這個樣子:

myModule.directive('creationEmitter', function() { 
    return { 
     restrict: 'A', 
     compile: function compile(tElement, tAttrs, transclude) { 
      return { 
       pre: function (scope, iElement, iAttrs, controller) { 
        scope.$emit('preCompile', iElement) 
       }, 
       post: function (scope, iElement, iAttrs, controller) { 
        scope.$emit('postCompile', iElement) 
       } 
      } 
     }, 
     link: function (scope, iElement, iAttrs) { 
      scope.$emit('link', iElement) 
     } 
    }; 
}); 

您現在可以聽的控制器,這是在DOM中給定的元素上面(子元素使用$broadcast)所有這些事件。

+0

我不認爲這是數據處理後的反應問題。看起來他正確地處理了從服務返回的承諾(我假設)。 我認爲發生的事情是在調用scrollto時會丟失DOM元素。他將數據加載到名爲prosItems的模型中,然後滾動到屏幕上的某個位置。我猜這個位置是基於ng-repeat完成並插入新的DOM節點。發生了什麼事情是,它將滾動到HTML插入到DOM中之前。 –

+0

是的,這就是發生了什麼事。盧卡斯的解決方案確實有所幫助,我爲此感謝他:當我特別將解決方案與ng重複結合時,我實現了我所需要的。但是如果有人知道等待dom渲染完成的更一般的解決方案,那麼閱讀一下會很有趣。 –

+0

@Hattan:我並不是在談論服務返回的諾言,而是羅伯特正在創造自己。對於一般方法:更新我的答案。 –

0

它可能鏈承諾並做中間處理。 直接回調必須返回下一個將收到的內容。

我沒有看到這種方法的任何直接的問題:

prosFactory.getPros() 
    .then(processCb) 
    .then(doSomethingWithProcessedDataCb) 
    .catch(errorCb) 
    .finally(scrollWindowCb) 

退房的documentation,它實際上是相當不錯的。