Khi nào thì sử dụng ko.utils.unwrapObservable?


114

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 nào sử dụng ko.utils.unwrapObservable(item)Nhìn vào mã, lệnh gọi đó về cơ bản sẽ kiểm tra xem liệu itemcó thể quan sát được hay không. Nếu đúng, trả về giá trị (), nếu không, chỉ trả về giá trị. Nhìn vào phần Knockout về cách tạo liên kết tùy chỉnh, chúng có cú pháp sau:

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

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

Câu trả lời:


142

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

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


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ỉ hoạt động với các đối tượng có thể quan sát, vì vậy bạn có thể kiểm tra trước (ko.isObservable) rằng nó có thể quan sát được và sau đó bạn có thể tự do mở nó bằng (). Nếu bạn đang nhận một đối tượng có thể có các quan sát được lồng vào nhau, thì tốt hơn là 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 đưa một phiên bản chưa được bao bọc của đối tượng để chuyển vào tiện ích con 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 vật có thể quan sát và không quan sát được.
RP Niemeyer

2
Tôi đoán tôi đang bối rối với mục đích của ko.utils.unwrapObservablenó là gì. Nhìn vào mã, nó chỉ kiểm tra xem nó có thể quan sát được hay không và nếu có, Knockout sẽ gọi ()để lấy giá trị của giá trị có thể quan sát được, nếu không, nó chỉ trả về giá trị cho không thể 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 liên kết, tại sao tôi không thể luôn sử dụng ()?
arb

17
Bạn không biết liệu bạn đang vượt qua một điều có thể quan sát được hay không thể quan sát được trong một ràng buộc. Nói rằng tôi có myBindingvà ai đó ràng buộc tức là như thế nào data-bind="myBinding: myValue". myValuecó thể là một thuộc tính có thể quan sát được hoặc nó có thể chỉ là một thuộc tính đơn giản trên mô hình khung nhìn. Nếu nó chỉ là một thuộc tính và tôi gọi nó giống như một hàm, thì bạn sẽ gặp lỗi. ko.utils.unwrapObservablesẽ trả lại cho bạn giá trị một cách an toàn bất kể bạn có được thông qua một giá trị có thể quan sát được hay không.
RP Niemeyer

10
Tôi cũng khuyên bạn nên sử dụng viết tắt 'ko.unwrap' vì 'ko.utils.unwrapObservable' là một biểu thức rất dài.
Ivan Nikitin

3
@IvanNikitin - chắc chắn, chỉ muốn chỉ ra rằng ko.unwrapcó sẵn trong 3.0+. Nếu bạn đang sử dụng cũ hơn 3.0, thì ko.utils.unwrapObservablevẫn còn đó.
RP Niemeyer

12

Câu trả lời trước đó là đúng, nhưng tôi thường chuyển các hàm vào các ràng buộc 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 một thứ khác, v.v.). Những gì tôi thực sự cần là mở bất kỳ chức năng nào, ngay cả khi nó không thể quan sát được.

Sau đây mở một cách đệ quy MỌI THỨ:

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

Đây là một ví dụ về một ràng buộc tùy chỉnh đơn giản mà 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, bindValue 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ó truyền vào một hàm, một hàm có thể quan sát được, một giá trị hay thậm chí là một hàm bên trong một hàm có thể quan sát được hay không. Thao tác này sẽ mở đúng cách mọi thứ cho đến khi nó đến được đối tượng tôi muốn.

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.