0

Currently i am using knockout 2.1.0 where following datepicker binding working perfectly for non observable value.When i have updated knockout 3.0 it is not working

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

When i debug the code i came to know that is allBindingsAccessor()._ko_property_writers is undefined .because of which i am not able to update the nonobservable value.

JsFIddle

Can anybody suggest me the solution for above code in 3.0 version

By using below example i have modified the my custom binding and it is working great .Please find the Updated fiddle

Updated Fiddle

4

1 回答 1

1

问题是这_ko_property_writers是一个私有的实现细节(这就是为什么名称是前缀的原因_)。如果您阅读源代码中的第 188-195 行以进行淘汰赛中的表达式重写,您会看到它说明了以下内容:

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

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

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

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

_twoWayBindings设置(可能会在任何未来版本的淘汰赛中消失,因为它不是真正的公共 API,不幸的是)是您可以在创建时设置的标志bindingHandler,告诉淘汰赛_ko_property_writers为您的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如果它不是可观察对象。

于 2014-04-12T13:25:57.470 回答