2012-05-02 33 views
5

Tôi có một ràng buộc tùy chỉnh để xử lý tự động hoàn tất và khi người dùng chọn một mục từ tự động hoàn thành, tôi nói chuyện với máy chủ và thay thế text_field bằng tên rút gọn. Vấn đề là điều này kích hoạt chức năng 'cập nhật' của liên kết tùy chỉnh của tôi lần thứ hai.Knockout.js - làm cách nào để điều chỉnh các ràng buộc tùy chỉnh

Knockout.js mã (chỉnh sửa: Lưu ý những điều sau đây được 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() 

Xem

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

Có cách nào để áp dụng một van tiết lưu để một ràng buộc tùy chỉnh?

Tôi chỉ muốn dừng chức năng cập nhật liên kết 'tùy chỉnh' từ kích hoạt lần thứ hai khi tôi đặt task.name thành short_name được gửi lại từ máy chủ.

Trả lời

3

Nói chung, tôi đã tìm thấy một mô hình như thế này để làm việc cho tôi

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

điều quan trọng là bạn thêm tùy chọn disposeWhenNodeIsRemoved để cho phép ràng buộc tính toán mới được xử lý đúng cách, nếu không bạn sẽ bị rò rỉ bộ nhớ và hiệu suất giảm hoặc tệ hơn. –

2

Nếu bạn không muốn vi phạm cách ly, vì vậy bạn có thể sử dụng tùy chọn chậm trễ của tự động hoàn thành và sự kiện chọn, hãy bỏ chức năng cập nhật.

Sửa init của bạn theo cách này:

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

cập nhật của bạn được gọi là một lần thứ hai vì (đối với đơn giản hóa) cập nhật là một số loại tính riêng của mình. Vì vậy, nó đăng ký mọi quan sát được truy cập bên trong nó. Trong dòng này unless task.name() == undefined bạn đăng ký cập nhật lên task.name(). Sau đó, khi bạn cập nhật quan sát của mình với task.name(data.short_name) về thành công của yêu cầu ajax, hãy cập nhật thông báo và tính toán lại.

+0

btw, những gì tran.dr_name() là? – ILya

+0

tran.dr_name() là lỗi đánh máy, được đổi thành task.name(). – map7

+0

Vì vậy, tôi thêm giải thích tại sao cập nhật của bạn được gọi là lần thứ hai – ILya

Các vấn đề liên quan