2012-03-08 37 views
106

Tôi đã viết một vài ràng buộc tùy chỉnh bằng KnockoutJS. Tôi vẫn không chắc chắn khi sử dụng ko.util.unwrapObservable(item) Nhìn vào mã, cuộc gọi đó về cơ bản kiểm tra xem liệu item có phải là một quan sát hay không. Nếu có, hãy trả về giá trị(), nếu không, chỉ trả về giá trị. Nhìn vào phần trên Knockout về việc tạo ra các ràng buộc tùy chỉnh, họ có cú pháp như sau:Khi nào nên sử dụng ko.utils.unwrapObservable?

var value = valueAccessor(), allBindings = allBindingsAccessor(); 
var valueUnwrapped = ko.utils.unwrapObservable(value); 

Trong trường hợp này, họ gọi thể quan sát được qua () nhưng sau đó cũng gọi ko.utils.unwrapObservable. Tôi chỉ cố gắng để có được một xử lý về khi sử dụng một so với khác hoặc nếu tôi chỉ nên luôn luôn làm theo các mô hình trên và sử dụng cả hai.

Trả lời

135

Bạn nên sử dụng ko.utils.unwrapObservable trong trường hợp bạn không biết mình có được chấp nhận hay không. Điều này thường là trong một ràng buộc tùy chỉnh, nơi một quan sát hoặc không thể quan sát có thể bị ràng buộc chống lại nó.

Trong mã mà bạn có ở trên, cuộc gọi đến valueAccessor() không thực sự là unwrapping một quan sát được. Nó chỉ là lấy giá trị đã được chuyển đến ràng buộc trong bối cảnh chính xác (nó được bọc trong một hàm để bảo vệ nó). Giá trị trả lại của valueAccessor() có thể là một quan sát hay không. Nó là bất cứ điều gì đã được thông qua để ràng buộc.

+0

Vì vậy, đây là mô hình mà tôi đã đăng thực hành tốt nhất cho các ràng buộc tùy chỉnh về sau? – arb

+4

Nó thực sự phụ thuộc vào tình hình. Một số ràng buộc tùy chỉnh được thiết kế để chỉ làm việc với các quan sát, vì vậy bạn có thể kiểm tra phía trước (ko.isObservable) rằng nó là một quan sát và sau đó bạn sẽ được tự do để unwrap nó với(). Nếu bạn đang nhận một đối tượng có thể có các quan sát lồng nhau, thì tốt hơn bạn nên thực hiện 'ko.toJS (yourObject)' thay vì sử dụng 'ko.utils.unwrapObservable', nếu bạn đang cố gắng lấy một phiên bản chưa được mở của đối tượng để chuyển vào một tiện ích hoặc thư viện của bên thứ ba. Nói chung, an toàn nhất là sử dụng 'ko.utils.unwrapObservable' để hỗ trợ các quan sát và không quan sát được. –

+2

Tôi đoán tôi đang bối rối với mục đích của 'ko.utils.unwrapObservable' là gì. Nhìn vào mã, nó chỉ kiểm tra xem nó có thể quan sát được hay không, Knockout gọi '()' để nhận giá trị của quan sát, ngược lại, nó chỉ trả về giá trị cho không quan sát được. Nếu tất cả những gì tôi quan tâm là giá trị của dữ liệu được truyền vào trong ràng buộc, tại sao tôi không thể luôn luôn sử dụng '()'? – arb

9

Câu trả lời trước là đúng, nhưng thường tôi chuyển các hàm vào các liên kết tùy chỉnh (một hàm kiểm tra quyền hoặc xác định việc cần làm dựa trên thứ gì đó khác, v.v.). Những gì tôi thực sự cần là cởi bỏ bất kỳ chức năng nào, ngay cả khi nó không thể quan sát được.

Sau đây đệ quy unwraps tất cả mọi thứ:

ko.utils.unwrapFunction = function (func) { 
    if (typeof func != 'function') { 
     return func; 
    } 
    else { 
     return ko.utils.unwrapFunction(func()); 
    } 
}; 

Dưới đây là một ví dụ về một tùy chỉnh đơn giản ràng buộc tôi đã viết:

//replaces single and double 'smart' quotes users commonly paste in from word into textareas and textboxes with normal text equivalents 
//USAGE: 
//data-bind="replaceWordChars:true 
//also works with valueUpdate:'keyup' if you want" 

ko.bindingHandlers.replaceWordChars = { 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     var bindingValue = ko.utils.unwrapFunction(valueAccessor); 

     if (bindingValue) { 
      $(element).val(removeMSWordChars(allBindingsAccessor().value())); //update DOM - not sure why I should need to do this, but just updating viewModel doesn't always update DOM correctly for me 
      allBindingsAccessor().value($(element).val()); //update viewModel 
     } 
    } 
} 

Bằng cách này bindingValue luôn chứa một giá trị. Tôi không cần phải lo lắng về việc liệu tôi có vượt qua được một chức năng hay không, một giá trị quan sát được, hoặc thậm chí là một chức năng bên trong một cái quan sát được. Điều này sẽ unwrap đúng tất cả mọi thứ cho đến khi nó được ở đối tượng tôi muốn.

Hy vọng rằng sẽ giúp ai đó.

+9

Tôi không ghi đè bất cứ điều gì, unwrapObservable vẫn còn đó, tôi được gọi là unwrapFunction. ko.utils là một không gian tên logic cho việc này vì nó là một hàm tiện ích loại bỏ. Tôi đồng ý một chút lộn xộn nhưng quyết định đặt điều này vào không gian tên đó vì lý do tương tự mà plugin ánh xạ đặt chính nó vào không gian tên mặc dù nó không đi kèm với ko, có một không gian tên hoàn toàn mới cho điều này dường như không đáng giá. – pilavdzice

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