2013-07-23 20 views
1

考慮一個應用程序,其中可以通過給文本字段提供輸入來觸發數據庫搜索,然後按下回車鍵。搜索結果應該在之後立即顯示。AngularJS:通過輸入觸發功能的推薦方式

要做到這一點,我創建了一個輸入元素並賦予它一個指令屬性:

<input search-shipment type="text"> 

// Directive 

Shipment.directive('searchShipment',function(){ 
    return{ 
     restrict: 'A', 
     link: function(scope,element){ 
      element.bind('keydown',function(e){ 
       if (e.which === 13){ 
        scope.shipment.fetchShipment(); 
       } 
      }) 
     } 
    } 
}); 

的功能被觸發:

Shipment.prototype.fetchShipment = function(){ 

    $http.post('../sys/core/fetchShipment.php',{ 
     // some data to POST 

    }).success(function(data){ 
      console.log(data); 
     }); 
     console.log(finished); 
}; 

這引起了一些怪異的行爲。該功能被觸發,並且「完成」被記錄到控制檯。然而,success()顯然觸發下旬,data沒有登錄,直到我做這必須是不同的東西比回報

現在我想通了,我可以用形式包裝避免這種行爲的另一輸入爲我的輸入元素,然後使用ng-submit來觸發我的功能。

但是,我想知道一些事情:

  • 爲什麼我的第一次,指導基礎的解決方案無法正常工作?
  • 如何在不使用表單的情況下完成我的目標?
  • 即使使用工作表單解決方案,第二個console.log()也會在之前觸發記錄數據。爲什麼是這樣?
+1

作爲第三點的答案:'console.log(data)'在回調函數中,它只在收到對HTTP請求的響應後觸發。由於'console.log(finished)'在回調之外,它將在HTTP請求完成後立即執行。 – godfrzero

+2

除了@godfrzero - $ http有'always()'方法(從1.1.5版本開始),你可以把'console.log(已完成)'放在哪裏。 –

回答

2

,好不容易纔根據說明來診斷是肯定的,沒有活的代碼,但有2件事這裏要注意:

  • 您的問題可能與使用$http從AngularJS 1.1.x版本的添加請求攔截器的地方。因此$http調用需要在$digest循環內完成。嘗試包你的電話到scope.$apply就像這樣:

    link: function(scope,element){ 
         element.bind('keydown',function(e){ 
          if (e.which === 13){ 
           scope.$apply(function(){ 
            scope.shipment.fetchShipment(); 
           }); 
    
          } 
         }) 
        } 
    
  • ,如果你使用的是1.1.x的,無論如何,你可以使用現有的ngKeyDown指令,而不是推出自己的。