1

目前使用 msDropDown 3.2 使控件看起来很漂亮,但是由于正在开发的应用程序的性质,我已经研究过使用 Knockout JS 来处理 UI 数据绑定。不幸的是,每当我更改视图模型上的属性时,它都会更改选择而不是渲染控件(我知道更改渲染控件所需的代码,但不确定如何将其挂钩到 Knockout)。

有没有人集成了这两个工具,如果有,那么你是如何让它们很好地结合在一起的?

编辑:

HTML:

<select data-bind="value: Type">
   <option value="1">First</option>
   <option value="2">Second</option>
   <option value="3">Third</option>
   <option value="4">Fourth</option>
</select>

JavaScript:

function ViewModel() {
    var self = this;
    self.Name = ko.observable();
    self.Type = ko.observable();
    self.IsVisible = ko.computed(function () {
        return this.Type() == 1;
    }, this);
}

var vm = new ViewModel();

ko.applyBindings(vm);

$(document).ready(function () {
    $("select").msDropDown();
});

从上面的代码可以看出,我正在创建一个 ViewModel 实例,然后应用绑定并启动 msDropDown。

如果我要调用以下命令:

vm.Type("2");

然后它将更新基础选择,但不会更新 msDropDown 控件的前端。基本上需要一种方法来挂钩 Knockout 在更改属性时可能调用的事件,以便我可以确定它是否是一个选择并调用一些特定于 msDropDown 的代码来更新 UI。

谢谢,

克里斯。

4

3 回答 3

2

感谢您的所有回答,但是我设法找到了一个涉及创建自己的活页夹的解决方案:

ko.bindingHandlers.setValue = {
    init: function (a, b, c) {
        var value = ko.utils.unwrapObservable(b());

        if (typeof value == 'undefined') {
           value = $(a).find("option").first().val();
        }
        $(a).val(value).change(function(){
            var observable = b();
            observable($(this).val());
        }).msDropdown();
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        var value = valueAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(value);
        // Get the value from the observable and set the value on the msDropDown.
        $(element).msDropDown().data("dd").set("value", valueUnwrapped);
    }
};

function ViewModel() {
    var self = this;
    self.Name = ko.observable();
    self.Type = ko.observable();
    self.IsVisible = ko.computed(function () {
        return this.Type() == 1;
    }, this);
}

var vm = new ViewModel();

ko.applyBindings(vm);

然后在 HTML

<select name="myselect" data-bind="setValue: Type">
    <option value="1">1</option>
    <option value="2">2</option
    <option value="3">3</option
    <option value="4">4</option
</select>

这会将 msDropDown 插件应用于选择,并且每当视图模型更改时,它都会更新底层选择和 msDropDown 生成的 UI 元素。此外,当更新 UI 中的选定项目时,它会保留回视图模型。

感谢您的所有帮助,希望其他尝试将 Knockout JS 与 msDropDown 一起使用的人会发现这很有帮助。

克里斯。

于 2012-12-11T10:55:43.053 回答
1

正如 MarcoK 所说,您需要订阅更改

我假设您不会使用静态下拉菜单(我可能错了)
在这种情况下,您还可以在 UI 中使用 afterAdd 绑定来调用您的 updateUI 方法 - 基本上确保在添加每个项目后,updateUI函数被调用(重新应用,msDropDown()以便您的项目正确显示

function ViewModel() {
    var self = this;
    self.Name = ko.observable();
    self.Type = ko.observable();
    self.IsVisible = ko.computed(function () {
        return this.Type() == 1;
    }, this);

    self.updateUI = function(){
        $("select").msDropDown();
    }

    self.Type.subscribe(function(newValue) {
        updateUI();
    });

    //just added this as I assume you will be using a generated options list
    self.myOptions = ko.observableArray();
}

你的标记变成:

<select data-bind="value: Type, options: myOptions, afterAdd: updateUI">
</select>

有关模板绑定的更多信息:http: //knockoutjs.com/documentation/template-binding.html

于 2012-12-10T12:24:32.297 回答
0

要创建钩子,你subscribe可以观察到(在你的 VM 中):

self.Type.subscribe(function(newValue) {
    // Use "newValue" to read the new value, which you can use
    // to bind to msDropDown / the UI
});
于 2012-12-10T11:55:25.830 回答