0

現在、私はノックアウト 2.1.0 を使用しています。次の日付ピッカー バインディングは、観測不可能な値に対して完全に機能します。ノックアウト 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バージョンの上記のコードの解決策を誰かに提案してもらえますか

以下の例を使用して、カスタムバインディングを変更しましたが、うまく機能しています。更新されたフィドルを見つけてください

更新されたフィドル

4

1 に答える 1

1

問題は、それ_ko_property_writersが非公開の実装の詳細であることです (そのため、名前の前に が付きます_)。ノックアウトで式を書き換えるソース コードの 188 ~ 195 行を読むと、次のように記述されていることがわかります。

バインディングを「双方向」として明示的に宣言することは、長期的には理想的ではありません (すべてのバインディングが公式の「プロパティ ライター」API を使用できることを宣言する必要なく使用できるとよいでしょう)。ただし、これは公開 API ではなく、公開されたこともないため (_ko_property_writers は文書化されていません)、短期的には内部実装の詳細として受け入れられます。

カスタム バインディングで _ko_property_writers に依存している開発者のために、KO 3.0 へのアップグレードを比較的簡単にするドキュメント化されていない機能として _twoWayBindings を公開します。ただし、これはまだ公式のパブリック API ではなく、実際のパブリック プロパティ ライター API を作成する場合、いつでも削除する権利を留保します。

_twoWayBindingsそのため、将来のバージョンに変更されない公開 API はまだないように思われますが、そのような API が決定されて提供されるまでは使用できるはずです。

UPDATED 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 に答える