2012-02-21 51 views
9

我在同一個項目中同時使用Knockout(版本2.0)和jQuery Mobile(版本1.0.1)。問題是將數據綁定到選擇列表。 jQuery Mobile提供了選擇列表,其中看似選擇的值和實際列表是單獨的元素。這是通過執行Knockout和jQuery Mobile:將數據綁定到選擇列表

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

在更改列表或選定的值之後。根據我的經驗,這是一個危險的情況,因爲開發人員經常忘記刷新選擇列表。

爲了緩解這一點,我編寫了自己的Knockout綁定處理程序。該值被綁定到選擇列表與下面的代碼:

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

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); 
     } 
    } 
}; 

本品採用天然options結合,但除此之外,它會自動刷新更改後的選擇列表列表值。然而,當我改變選定的值時,這有一個問題。如果我第一次設置列表值,我的jqmOptions刷新選擇列表,但在那一點上,選定的值尚未設置。我最終得到了一個選擇列表,其中包含所有正確的值,並在內部選擇了正確的選項,但jQuery Mobile仍然顯示默認值爲選中狀態。

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

淘汰賽不允許我先設置選擇的值,然後設置列表中的值,因爲在這種情況下,有沒有允許值時,我設置選定的值。因此選定的值總是未定義的。

是否有寫淘汰賽自定義綁定這將刷新選擇列表中的元素在這兩種情況下的方式:改變列表值和改變選擇的值時,是什麼時候?

目前我解決這種情況與下面的代碼:

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

這是不是很優雅的解決方案然而,我想解決這個問題更好。

回答

4

對於我個人的經驗(與jquerymobile 1.1.0和2.1.0 knockoutjs),我只用jqmoptions(如被看見在第一篇文章)結合有一個有效的淘汰賽結合的選擇。爲了使「價值」結合與選擇的作品,只是聲明爲第一在結合

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

看起來該訂單是必需的:http://goo.gl/nVbHc

+0

查看本博客文章:http://pieterderycke.wordpress.com/2012/09/22/creating- a-custom-knockout-binding-for-the-jquery-mobile-listview /它解釋了jQuery Mobile的自定義列表視圖綁定。 – MuSTaNG 2012-10-22 05:24:21

14

我結束了自己解決。我寫我自己jqmValue結合:

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); 
     } 
    } 
}; 

選擇列表代碼則改爲如下:

我已經試過問這個問題之前,這個昨天實現,但顯然我寫的不好那麼因爲它不起作用。然而,現在我用一雙新鮮的眼睛正確地實現了它,希望這個答案能夠解決其他Knockout和jQuery Mobile用戶的問題。

+0

偉大的作品!感謝威樂! – 2012-03-25 16:40:22

+2

在找到您的問答之前,我正在伸展頭髮。感謝分享 – 2012-08-10 13:38:02

+0

你是否更新過淘汰賽3?這對我來說似乎不適用於KO 3的 – 2014-06-20 02:44:16

0

只是爲了清楚起見,最好的解決方案現在KO 3 .X是:

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); 
     } 
    } 
    }; 

和匹配HTML使用:

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

同時使用基因敲除3.3 + jQuery Mobile的1.4.5和也有同樣的問題 當我有多個選擇,其結合一種值

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

第一/第二選擇未示出的初始化值和後第二不更新... 我終於用下面結合:(更換輸入的值:基於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) {} 
    } 
}; 
相關問題