2012-05-02 97 views
5

我有一個自定義綁定來處理自動完成,並且當用戶從自動完成中選擇一個項目時,我會與服務器交談並用縮寫名稱替換text_field。問題是這會再次觸發我的自定義綁定的「更新」功能。Knockout.js - 如何限制自定義綁定

Knockout.js代碼(編輯:注意下面是CoffeeScript的):

ko.bindingHandlers.ko_autocomplete = 
    init: (element, params) -> 
    $(element).autocomplete(params()) 

    update: (element, valueAccessor, allBindingsAccessor, viewModel) -> 
    unless task.name() == undefined 
     $.ajax "/tasks/name", 
     data: "name=" + task.name(), 
     success: (data,textStatus, jqXHR) -> 
      task.name(data.short_name) 


    Task = -> 
    @name = ko.observable() 
    @name_select = (event, ui) -> 
     task.name(ui.item.name) 
     false 

    task = Task.new() 

查看

= f.text_field :name, "data-bind" => "value: name, ko_autocomplete: { source: '/autocomplete/tasks', select: name_select }" 

是否有節氣門適用於自定義綁定的方法嗎?

我只想停止自定義綁定的'更新'功能,當我將task.name設置爲從服務器發送回來的短名稱時再次觸發。

回答

3

一般情況下,我發現這樣的模式爲我工作

ko.bindingHandlers.gsExample = 
    update: (element, valueAccessor, allBindingsAccessor, viewModel) -> 
     args = valueAccessor() 

     # Process args here, turn them into local variables 
     # eg. 
     span = args['span'] || 10 

     render = ko.computed -> 
      # Put your code in here that you want to throttle 
      # Get variables from things that change very rapidly here 

      # Note: You can access variables such as span in here (yay: Closures) 
      some_changing_value = some_observable() 

      $(element).html(some_changing_value) 

     # Now, throttle the computed section (I used 0.5 seconds here) 
     render.extend throttle : 500 

     # Cause an immediate execution of that section, also establish a dependancy so 
     # this outer code is re-executed when render is computed. 
     render() 
+2

添加disposeWhenNodeIsRemoved選項以允許正確處理新的計算綁定至關重要,否則會導致內存泄漏並降低性能或更糟糕。 –

2

如果你不想違反隔離,所以你可以使用自動完成的延遲選項,它是選擇事件,拋出更新功能。

修改這樣你的初始化:

var options = $.extend(params(), { 
     select: function(ev, ui) { 
     var name = ui.item ? ui.item.short_name : this.value 
     task.name(name); 
     } 
    }) 
    $(element).autocomplete(options) 

你的更新被稱爲第二次,因爲(爲了簡化)更新是某種計算本身。所以它訂閱了它內部的所有可觀察對象。在此行unless task.name() == undefined您訂閱更新到task.name()。然後,當您更新您的可觀察的成功的ajax請求task.name(data.short_name)時,更新得到通知並重新計算。

+0

順便說一句,什麼tran.dr_name()是什麼? – ILya

+0

tran.dr_name()是拼寫錯誤,更改爲task.name()。 – map7

+0

因此,我添加一個解釋爲什麼你的更新第二次被調用 – ILya