【问题标题】:ko.bindingHandlers.datepicker not working for knockout version 3.0ko.bindingHandlers.datepicker 不适用于淘汰赛版本 3.0
【发布时间】:2014-04-10 15:02:11
【问题描述】:

目前我正在使用淘汰赛 2.1.0,其中以下 datepicker 绑定非常适合不可观察的值。当我更新淘汰赛 3.0 时,它无法正常工作

ko.bindingHandlers.datepicker = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        // Get the options from the binding.
        var options = allBindingsAccessor().datepickerOptions || {};

        $(element)
      .datepicker(options)
      .bind("change", function() {
          ko.bindingHandlers.datepicker.updateValue(element, valueAccessor, allBindingsAccessor);
      });

        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $(element).datepicker("destroy");
        });
    },
    update: function(element, valueAccessor, allBindingsAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());

        // If the date is coming from a Microsoft webservice.
        if (typeof value === "string" && value.indexOf('/Date(') === 0) {
            value = new Date(parseInt(value.replace(/\/Date\((.*?)\)\//gi, "$1")));
        }
        var currentDate = $(element).datepicker("getDate");

        // Check if the date has changed.
        if (value && value - currentDate !== 0) {
            $(element).datepicker("setDate", value);
        }
    },
    updateValue: function(element, valueAccessor, allBindingsAccessor) {
        var observable = valueAccessor(),
        dateValue = $(element).datepicker("getDate");

        // Two-way-binding means a writeable observable.
        if (ko.isWriteableObservable(observable)) {
            observable(dateValue);
            return;
        }
        if (allBindingsAccessor()._ko_property_writers) {
            allBindingsAccessor()._ko_property_writers.datepicker(dateValue);
        }
    }
};

当我调试代码时,我知道allBindingsAccessor()._ko_property_writers 是未定义的。因为我无法更新不可观察的值。

JsFIddle

谁能给我建议3.0版本的上述代码的解决方案

通过使用下面的示例,我修改了我的自定义绑定,它工作得很好。请找到更新的小提琴

Updated Fiddle

【问题讨论】:

    标签: jquery knockout.js datepicker knockout-2.0 knockout-3.0


    【解决方案1】:

    问题在于_ko_property_writers 是一个私有的实现细节(这就是为什么名称以_ 为前缀的原因)。如果您阅读line 188-195 in the source code for expression rewriting in knockout,您会看到它声明如下:

    从长远来看,将绑定明确声明为“双向”并不理想(如果所有绑定都可以使用官方的“属性编写器”API 而无需声明它们可能会更好)。但是,由于这不是,也从来不是公共 API(_ko_property_writers 从未记录在案),因此在短期内作为内部实现细节是可以接受的。

    对于那些在自定义绑定中依赖 _ko_property_writers 的开发人员,我们将 _twoWayBindings 公开为一个未记录的功能,它可以相对轻松地升级到 KO 3.0。但是,这仍然不是一个官方的公共 API,如果我们创建一个真正的公共财产作家 API,我们保留随时删除它的权利。

    因此,似乎仍然没有不会更改为未来版本的公共 API,但在决定并提供此类 API 之前,您应该能够使用 _twoWayBindings

    2014-04-15 更新 - 添加设置双向绑定标志的示例

    _twoWayBindings 设置(可能会在任何未来版本的淘汰赛中消失,因为它不是真正的公共 API,不幸的是)是您可以在创建 bindingHandler 时设置的标志,以告诉淘汰赛创建 @987654329 @ 条目为您的bindingHandler。设置此标志的方式与创建新 bindingHandler 的方式类似:

    ko.expressionRewriting._twoWayBindings['simpleTwoWayBinding'] = true;
    

    一个完整的绑定示例,可以通过两种方式绑定到不可观察的属性:

    ko.expressionRewriting._twoWayBindings['simpleTwoWayBinding'] = true;
    ko.bindingHandlers['simpleTwoWayBinding'] = {
        init: function(element, valueAccessor, allBindings, viewModel){
            element.value = valueAccessor();
            var valueSetter = allBindings.get('_ko_property_writers').simpleTwoWayBinding;
            element.addEventListener('change', function(){
                valueSetter(element.value);
            });
        }
    };
    

    我有一个工作示例,您可以在 http://jsfiddle.net/p8ugz/ 找到它

    但是,请注意上述代码不适用于可观察属性。要同时支持两者,您需要检查它是否绑定到可观察对象,在这种情况下仅使用普通可观察对象,如果不是可观察对象,则使用 _ko_property_writers

    【讨论】:

    • 如果您可以编辑您的问题并添加minimal example 并使用最小示例描述问题,我会看看是否可以让最小示例正常工作。跨度>
    • 是的,您已经编写了一个示例。但是,您的问题是关于淘汰赛特定的事情,而您的小提琴有五个外部库。 jsfiddle 上的示例展示的不仅仅是最低要求;这将只是创建一个简单的带有淘汰赛的双向绑定。此外,您的示例不会讨论您在被告知_twoWayBindings 标志后遇到的问题。不过,我已经用一个为自定义bindingHandler 设置_twoWayBindings 标志的示例更新了我的答案。
    • 感谢 Robert 的示例..我已经修改了插件。现在可以更改 nonobservable 的值..
    猜你喜欢
    • 2018-03-25
    • 2020-06-22
    • 2014-08-05
    • 2013-03-30
    • 2013-01-13
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    相关资源
    最近更新 更多