2012-02-21 25 views
9

Tôi đang sử dụng cả Knockout (phiên bản 2.0) và jQuery Mobile (phiên bản 1.0.1) trong cùng một dự án. Vấn đề là với dữ liệu ràng buộc để chọn danh sách. jQuery Mobile trình bày các danh sách lựa chọn theo cách mà giá trị dường như được chọn và danh sách thực tế là các phần tử riêng biệt. Điều này được khắc phục bằng cách thực hiệnKnockout và jQuery Mobile: Dữ liệu ràng buộc để chọn danh sách

$(element).selectmenu('refresh', true); 

sau khi thay đổi danh sách hoặc giá trị đã chọn. Dựa trên kinh nghiệm của tôi, đây là một tình huống nguy hiểm vì các nhà phát triển thường quên làm mới danh sách lựa chọn.

Để giảm bớt điều này, tôi đã viết trình xử lý ràng buộc Knockout của riêng mình. Các giá trị này được ràng buộc với danh sách lựa chọn với đoạn mã sau:

<select name="selection" data-bind="jqmOptions: values, optionsValue: 'id', optionsText: 'name', value: selectedValue"> 
</select> 

Việc thực hiện jqmOptions:

ko.bindingHandlers.jqmOptions = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     if (typeof ko.bindingHandlers.options.init !== 'undefined') { 
      ko.bindingHandlers.options.init(element, valueAccessor, allBindingsAccessor, viewModel); 
     } 
    }, 

    update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     if (typeof ko.bindingHandlers.options.update !== 'undefined') { 
      ko.bindingHandlers.options.update(element, valueAccessor, allBindingsAccessor, viewModel); 
     } 

     var instance = $.data(element, 'selectmenu'); 
     if (instance) { 
      $(element).selectmenu('refresh', true); 
     } 
    } 
}; 

này sử dụng có nguồn gốc options ràng buộc nhưng thêm vào đó, nó sẽ tự động làm mới chọn danh sách sau khi thay đổi giá trị danh sách. Tuy nhiên, có vấn đề với điều này khi tôi thay đổi giá trị đã chọn. Nếu trước tiên tôi đặt giá trị danh sách, jqmOptions của tôi sẽ làm mới danh sách chọn nhưng tại thời điểm đó, giá trị đã chọn chưa được đặt. Tôi kết thúc với một danh sách lựa chọn, trong đó có tất cả các giá trị chính xác và tùy chọn bên trong bên phải được chọn, nhưng jQuery Mobile vẫn hiển thị giá trị mặc định như được chọn.

this.values(someArrayOfValues); 
this.selectedValue(oneOfTheArrayValues); 

Loại trừ không cho phép tôi đặt giá trị danh sách trước và sau đó đặt giá trị danh sách, vì trong trường hợp này không có giá trị được phép khi tôi đặt giá trị đã chọn. Do đó giá trị được chọn luôn không xác định.

Có cách nào để viết liên kết tùy chỉnh Knockout mà sẽ làm mới phần tử danh sách chọn trong cả hai trường hợp: khi thay đổi giá trị danh sách và khi thay đổi giá trị đã chọn?

Hiện nay tôi giải quyết tình huống này với đoạn mã sau:

this.values(someArrayOfValues); 
this.selectedValue(oneOfTheArrayValues); 
this.values(someArrayOfValues); 

Đây không phải là giải pháp rất thanh lịch tuy nhiên và tôi muốn giải quyết nó tốt hơn.

Trả lời

4

Đối với kinh nghiệm cá nhân của tôi (với jquerymobile 1.1.0 và knockoutjs 2.1.0), tôi chỉ sử dụng jqmoptions (như đã xem trong bài đăng đầu tiên) có ràng buộc ràng buộc hợp lệ.Để thực hiện tác phẩm 'giá trị' ràng buộc với lựa chọn, chỉ đơn giản là khai báo nó như đầu tiên trong ràng buộc

<select name="myname" id="myid" data-bind="value: myvalue, jqmoptions: myvalues, optionsValue: 'id', optionsText: 'desc'"></select> 

Trông rằng thứ tự là bắt buộc: http://goo.gl/nVbHc

+0

Hãy xem bài viết blog này: http://pieterderycke.wordpress.com/2012/09/22/creating- a-custom-knockout-binding-cho-the-jquery-mobile-listview/Nó giải thích một ràng buộc listview tùy chỉnh cho jquery di động. – MuSTaNG

14

Tôi đã tự giải quyết xong. Tôi đã viết jqmValue riêng tôi ràng buộc:

ko.bindingHandlers.jqmValue = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     if (typeof ko.bindingHandlers.value.init !== 'undefined') { 
      ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel); 
     } 
    }, 

    update: function (element, valueAccessor, allBindingsAccessor, viewModel) { 
     if (typeof ko.bindingHandlers.value.update !== 'undefined') { 
      ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, viewModel); 
     } 

     var instance = $.data(element, 'selectmenu'); 
     if (instance) { 
      $(element).selectmenu('refresh', true); 
     } 
    } 
}; 

Các chọn đang danh sách sau đó được đổi thành sau:

Tôi đã cố gắng thực hiện ngày hôm qua điều này trước khi đặt câu hỏi, nhưng dường như tôi đã viết nó kém sau đó bởi vì nó không hoạt động. Tuy nhiên, bây giờ với một đôi mắt mới tôi quản lý để thực hiện nó một cách chính xác vì vậy hy vọng câu trả lời này giải quyết vấn đề cho người dùng Knockout và jQuery Mobile khác.

+0

Hoạt động tuyệt vời! Cảm ơn Ville! –

+2

Tôi đã duỗi tóc trước khi tìm kiếm Giải Đáp. Cảm ơn bạn đã chia sẻ –

+0

bạn đã cập nhật điều này cho loại trực tiếp 3 chưa? điều này dường như không làm việc cho tôi bây giờ –

0

Chỉ cần cho rõ ràng, giải pháp tốt nhất hiện nay cho KO 3 .x sẽ là:

ko.bindingHandlers.jqmValue = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     if (typeof ko.bindingHandlers.value.init !== 'undefined') { 
     ko.bindingHandlers.value.init(element, valueAccessor, allBindingsAccessor, viewModel); 
     } 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) { 
     var instance; 
     if (typeof ko.bindingHandlers.value.update !== 'undefined') { 
     ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, viewModel); 
     } 
     instance = $.data(element, 'mobile-selectmenu'); 
     if (instance) { 
     $(element).selectmenu('refresh', true); 
     } 
    } 
    }; 

Và việc sử dụng phù hợp với HTML:

<select data-bind="options: optionsList, optionsValue: 'Id', optionsText: 'Title', jqmValue: knockoutobservable"></select> 
0

sử dụng cả hai Knockout 3.3 + jQuery Mobile 1.4.5 và cũng có cùng một vấn đề khi tôi có nhiều lựa chọn mà ràng buộc một giá trị

<select id="myselect1" data-bind="options: modelsA-Z, value: myModel"></select> 
<select id="myselect2" data-bind="options: modelsFamous, value: myModel"></select> 

1st/2nd chọn không hiển thị giá trị init và 2 không được cập nhật sau ... Cuối cùng tôi sử dụng dưới đây ràng buộc: (thay thế giá trị trên: myModel -> jqmValue: myModel)

ko.bindingHandlers.jqmValue = { 
    init: function (element, valueAccessor) { 
     var result = ko.bindingHandlers.value.init.apply(this, arguments); 
     try { 
      $(element).selectmenu("refresh"); 
     } catch (x) {} 
     return result; 
    }, 
    update: function (element, valueAccessor) { 
     ko.bindingHandlers.value.update.apply(this, arguments); 
     var value = valueAccessor(); 
     var valueUnwrapped = ko.utils.unwrapObservable(value); 
     try { 
      $(element).selectmenu("refresh"); 
     } catch (x) {} 
    } 
}; 
Các vấn đề liên quan