Knockout和jQuery Mobile:将数据绑定到选择列表

Vil*_*nen 9 jquery-mobile knockout.js

我在同一个项目中使用了Knockout(版本2.0)和jQuery Mobile(版本1.0.1).问题在于将数据绑定到选择列表.jQuery Mobile以一种看似选择的值和实际列表是单独元素的方式呈现选择列表.这是通过执行来解决的

$(element).selectmenu('refresh', true);
Run Code Online (Sandbox Code Playgroud)

更改列表或选定值后.根据我的经验,这是一个危险的情况,因为开发人员经常忘记刷新选择列表.

为了简化这一点,我编写了自己的Knockout绑定处理程序.使用以下代码将值绑定到选择列表:

<select name="selection" data-bind="jqmOptions: values, optionsValue: 'id', optionsText: 'name', value: selectedValue">
</select>
Run Code Online (Sandbox Code Playgroud)

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);
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

这使用本机options绑定,但除此之外,它会在更改列表值后自动刷新选择列表.但是当我更改所选值时,这有问题.如果我首先设置列表值,我的jqmOptions将刷新选择列表,但此时,尚未设置所选值.我最终得到一个选择列表,它具有所有正确的值,并在内部选择了正确的选项,但jQuery Mobile仍然显示默认值为selected.

this.values(someArrayOfValues);
this.selectedValue(oneOfTheArrayValues);
Run Code Online (Sandbox Code Playgroud)

Knockout不允许我首先设置所选值然后设置列表值,因为在这种情况下,当我设置所选值时没有允许的值.因此,所选值始终未定义.

有没有办法编写Knockout自定义绑定,在两种情况下都会刷新选择列表元素:更改列表值和更改选定值时?

目前我用以下代码解决了这种情况:

this.values(someArrayOfValues);
this.selectedValue(oneOfTheArrayValues);
this.values(someArrayOfValues);
Run Code Online (Sandbox Code Playgroud)

然而,这不是非常优雅的解决方案,我想更好地解决它.

Vil*_*nen 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);
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

然后将选择列表代码更改为以下内容:

在问这个问题之前我昨天已经尝试过这个,但显然我写的很糟糕,因为它不起作用.然而,现在有了一双新鲜的眼睛,我设法正确实现它,所以希望这个答案也解决了其他Knockout和jQuery Mobile用户的问题.

  • 在找到你的问答之前,我正在伸展自己的头发.感谢分享 (2认同)
  • 并确保`jqmValue`绑定位于元素绑定列表中的`options`绑定之后,或者它可能无法正确更新初始值 (2认同)

D_G*_*idi 4

根据我的个人经验(使用 jquerymobile 1.1.0 和 knockoutjs 2.1.0),我只使用jqmoptions(如第一篇文章中所示)绑定来将有效的淘汰赛绑定到选择。要使“值”绑定与 select 一起使用,只需将其声明为绑定中的第一个即可

<select name="myname" id="myid" data-bind="value: myvalue, jqmoptions: myvalues, optionsValue: 'id', optionsText: 'desc'"></select>
Run Code Online (Sandbox Code Playgroud)

看起来该命令是强制性的: http: //goo.gl/nVbHc