2014-01-15 23 views
0

爵士小提琴裏面的前值http://jsfiddle.net/suras/JzaV9/4/AngularJS從指令設置模型值並調用父作用域函數持有到該函數

這是我的指令

'use strict'; 

barterApp.directive('autosuggest', function($timeout, $http) { 
    return { 
    restrict: "E", 
    scope: { 
     modelupdate:"=", 
     suggestions:"=", 
     urlsend:"@" 
    }, 
    template: '<ul><li ng-repeat="suggest in suggestions" ng-click="updateModel(suggest)">{{suggest}}</li></ul>', 
    link: function (scope, element) { 
     scope.$watch('modelupdate', function() { 
     $timeout(function(){ 
      $http.post(scope.urlsend, {q:scope.modelupdate}).then(function(data){ 
      scope.suggestions = data.data; 
      console.log(data.data); 
      }); 
     }, 3000); 
     }); 
     scope.updateModel = function(value){ 
     scope.modelupdate = value; 
     scope.$parent.getBookInfo(); 
     } 
    } 
    }; 

}); 

控制器

barterApp.controller('openLibraryCtrl', ['$scope','$http',function ($scope,$http) { 
    $scope.title = ""; 
    $scope.getBookInfo = function(value){ 
     if($scope.title == "" || $scope.title == " ") //here title is 'r'(previous value) 
     { 
     return; 
     } 
     $http.get('/book_info.json?q='+$scope.title).then(function(res){ 
     if(Object.keys(res).length !== 0) 
     { 
      data = res.data 
      console.log(data); 

     } 
     }); 
    } 
    //here title is 'rails' (updated value from directive). 
    //(used a watch function here on model update 
    // and checked it but inside getBookInfo it is still 'r') 

}]); 

在更新模型函數中,我設置模型值並在父範圍上調用getBookInfo函數。但這裏的東西是(這是一個自動完成)時,我在包含ng模型的輸入字段中輸入值,例如'r'然後觸發手錶,然後我從後期url獲得建議(可以說「rails」 「搖滾」),並按照指令通過模板顯示。當我點擊其中一個建議(如'rails')時,它會觸發指令中的updatemodel函數並設置模型值。它的優良之處在於此,但是當我在父範圍中調用getBookInfo函數時,$ scope.title在函數內部是'r'(我使用控制檯日誌在函數外檢查模型值是否正確更新爲'rails')。再次當我點擊「搖滾」getBookInfo裏面的模型值是'rails'。 我不知道發生了什麼事。 (我還與控制器的監控功能測試的模型被正確地更新,但該函數調用getBookInfo保持回以前的值)

view 

<form ng-controller="openLibraryController"> 
<input type="text" ng-model="title" id="title" name="book[title]" /> 
    <autosuggest modelupdate = "title" suggestions = "book_suggestions" urlsend="/book_suggestions.json"> </autosuggest> 
</form> 
+1

創建小提琴傾向於產生更快,更好的答案的;) – gkalpak

+0

確定我將創建一個搗鼓它 – surendar

+0

爵士小提琴http://jsfiddle.net/suras/JzaV9/4/ – surendar

回答

1

我沒仔細端詳它,但我懷疑(高信心度),在調用getBookInfo()時,父範圍尚未更新(因爲我們仍處於$摘要週期的中間)。

不那麼好解決方案1:
您可以立即更新父範圍,以及(如scope.$parent.title = ...),但是這顯然是一個壞主意(出於同樣的原因爲NR 2,但更)。

不那麼好解決方案2:
你可以通過新的標題作爲參數傳遞給getBookInfo()

這兩種解決方案都會將控制器代碼與指令代碼混合在一起,並在組件之間建立緊密耦合,從而降低可重複使用性和可測試性。

不那麼糟糕的解決方案:
你可以觀看了標題,並調用getBookInfo()只要稍有改變:

$scope.$watch('title', function (newValue, oldValue) { 
    getBookInfo(); 
}); 

這將是罰款,除了事實,這是完全沒有必要的。


更好的解決方案:
角應該照顧的所有保在同步的東西對我們來說,它實際上沒有。關於調用getBookInfo()的目的,你沒有給出太多的背景知識,但我猜你打算用選定書上的一些信息來更新視圖。
在這種情況下,你可以將它綁定到一個元素(使用ng-bind),Angular將確保它正確和及時地執行。
例如:

<div>Book info: <span ng-bind="getBookInfo()"></span></div> 

此外,autosuggest指令不必知道任何有關它。它應該只關心顯示建議,操縱DOM(如有必要),並在點擊建議時更新指定的模型屬性(例如title)。你對更新後的價值所做的一切應該不成其事。

(順便說一句,最好的建議應該由服務提供。)


下面是解決問題的一個變形例(根據你的代碼)。如上所述有解決問題的幾種方法,我只是覺得這一個即將被更清潔,更一致的「角辦法」:

Book title: <input type="text" ng-model="book.title" /> 
<autosuggest modelupdate="book.title" 
      suggestions="book.suggest()"></autosuggest> 
Book info: <span ng-bind="book.getInfo()"></span> 

只要看一眼的HTML(不知道是什麼JS) ,可以容易地知道發生了什麼:

  1. 有一個文本字段綁定到book.title
  2. 有一個自定義autosuggest thingy,提供了book.suggest()提供的建議和更新book.title
  3. 有一個span顯示有關該書的信息。

相應的指令如下:

app.directive('autosuggest', function() { 
    return { 
     restrict: 'E', 
     scope: { 
      modelupdate: '=', 
      suggestions: '&' 
     }, 
     template: 
      '<ul><li ng-repeat="suggest in suggestions()" ' + 
        'ng-click="modelupdated = suggest">' + 
       '{{suggest}}</li></ul>' 
    }; 
}); 

正如你可以看到,所有的指令都知道的是如何獲取的建議,哪些更新。

請注意,相同的指令可以用於任何類型的「可建議的」(即使是沒有getBookInfo()的)。只需傳遞正確的屬性(modelupdated,suggestions)。 請注意,我們可以刪除autosuggest元素,如果沒有對HTML或JS進行任何進一步修改(在您的版本中,圖書信息將停止更新),應用程序將繼續按預期工作(沒有源代碼的建議)。


你可以找到完整版的這個short demo here

+0

感謝您的回答。我只是想知道爲什麼scope.title在調用getbookinfo()時沒有更新。所以問題在於消化週期。我也想過這個。但是爲什麼這種特殊情況下消化週期會有延遲,因爲雙向綁定對所有其他情況都是完美的。無論這是angular.js的問題還是這個概念都是錯誤的。 – surendar

+0

我不明白你的意思是_「雙向綁定對所有其他場景完美運行」_。還有哪些場景? – gkalpak

相關問題