knockout.js - requirejs w/knockoutjs w/select2 无法在第一次加载时更新 observable

标签 knockout.js requirejs jquery-select2 amd

我们第一次加载 requirejs 模块时,我的 View 模型中的可观察值似乎没有更新。但是当您评论 $("#ddl").select2(); 时,一切正常。

requirejs.config({
    'paths': {
        'jquery': '//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.0.min',
            'ko': '//ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0',
            'select2': '//ivaynberg.github.io/select2/select2-3.4.5/select2',
            'domReady': 
                '//cdnjs.cloudflare.com/ajax/libs/require-domReady/2.0.1/domReady'
    },
        'shim': {
        'select2': {
            deps: ['jquery'],
            exports: '$.select2'
        }
    }
});

define('simpleKo', ['jquery', 'ko', 'domReady', 'select2'],

function ($, ko, domReady) {
    var simpleViewModel = function () {
        var self = this;
        self.name = ko.observable();
        self.names = ko.observableArray(['John', 'Tim', 'Mike', 'Jay']);
    };

    domReady(function () {
        ko.applyBindings(new simpleViewModel());
        $("#ddl").select2({
            width: 'resolve'
        });
    });
});

requirejs(['simpleKo']);

JSFiddle 上有一个活生生的例子当您第一次打开没有缓存的链接时会失败。

我已经尝试了一切,有人对可能发生的事情有想法吗?

最佳答案

我对 select2 使用自定义绑定(bind)处理程序(在引导环境中):

<div data-bind="selectbox: { value: selectedValueId, values: values || [{id: 1, text: 'text'}], lookupId: 'id', lookupText: 'text', mode: 'id' }"/>

尽管它看起来太复杂,我在这里发布自定义绑定(bind)代码:

        ko.bindingHandlers["selectbox"] = {
        init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            return { controlsDescendantBindings: true };
        },
        update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
            var nullValue = ["Unselected"];

            var options = valueAccessor(), value = options.value, values = (ko.unwrap(options.values) || []).map(function (item) {
                return { id: ko.unwrap(item[options.lookupId || "id"]), text: ko.unwrap(item[options.lookupText || "text"]) || "(undelected)" };
            }), getId = (function (object) {
                return object.id;
            }), findValue = options.findValue || (function (id) {
                //console.log(id, values.filter((object) => { console.log(getId(object)); return getId(object) == id; }));
                return values.filter(function (object) {
                    return (getId(object) == id) || (id == '' && getId(object) == null);
                })[0];
            }), initialValue = (options.mode === "id" ? findValue(ko.unwrap(value)) : ko.unwrap(value)) || { text: "(undefined)" };

            //console.log(value());
            var $selectContainerTemplate = $("<div class='input-group' />");
            var $selectTemplate = $("<input type='hidden' style='width: 100%;' />");
            $selectContainerTemplate.append($selectTemplate);

            values = [{ id: null, text: "(undefined)" }].concat(values);

            $(element).children().remove();
            $(element).append($selectTemplate);
            $selectTemplate["select2"]({
                initSelection: function (element, callback) {
                    callback(ko.unwrap(initialValue));
                },
                data: values,
                id: getId
            });
            $selectTemplate.change(function (event) {
                //alert(event.val);
                var newValue = findValue(event["val"]);
                if (options.mode === "id") {
                    newValue = newValue["id"];
                }
                if (ko.isObservable(value)) {
                    value(newValue);
                } else {
                    value = newValue;
                }
            });
        }
    };

希望这会有所帮助。

关于knockout.js - requirejs w/knockoutjs w/select2 无法在第一次加载时更新 observable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26894479/

相关文章:

javascript - 如何根据下拉选择填充文本值类型的输入 - Angular 5

knockout.js - 将元素放入挖空 View 模型中

javascript - 使用数据模型中的 knockout 填充选择下拉列表

javascript - knockout 不会更改对象数组中的复选框状态

javascript - Requirejs:WAITING模块内的require函数

requirejs - 有没有更简洁的方法在 RequireJS 中包含依赖项

javascript - Select2.js v4.0 : How transmit filter text to ajax source data?

jquery - 如何使用 jquery 选择 select2 选择框的选项?

javascript - 有没有办法在不先声明数据参数的情况下访问 knockout 按键绑定(bind)中的第二个事件参数?

javascript - require js 中的交叉引用