2

KnockoutJS検証ライブラリのエラーへのリンクのリストを含む検証サマリーを作成しようとしています。それを表示するためのカスタムforeachハンドラーを作成する必要があります。

以下のコードで私が達成しようとしているのは、errors()リストの変更をリッスンし、検証の要約を作成する機能です。私は実際には「エラー」リストを使用しません(これは単なる文字列のリストであるため)が、変更をリッスンするために使用します。

私が見たもの(やや関連している)から、スコープが間違っています-「ko.applyBindingsToDescendants」のように子要素のViewModelを期待していますが、これを実装する方法がわかりません。

これは私の現在のバインディングコードです:

ko.bindingHandlers.validationSummary = {

    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

        function ValidationErrorModel(fieldRef, errorMessage) {
            this.fieldRef = ko.observable(fieldRef),
            this.errorMessage = ko.observable(errorMessage)
        }

        var currentValidationModel = ko.observableArray(),
            $validationElements = $(".validationElement");

        $validationElements.each(function (i, elem) {

            var $elem = $(elem),
                validationErrorModel = new ValidationErrorModel("#" + $elem.attr("name"), $elem.attr("title"));

            currentValidationModel.push(validationErrorModel);

        });

        console.log(currentValidationModel());
        ko.applyBindingsToDescendants({ foreach: currentValidationModel }, element);


        return { controlsDescendantBindings: true };
    },

    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

    }
};

そして私のテンプレート:

<ul data-bind="validationSummary: errors">
    <li>
        <a data-bind="attr: { href: fieldRef }, text: errorMessage"></a>
    </li>
</ul>
4

1 に答える 1

2

Stackoverflowユーザーの@antishokは、#knockoutjsIRCチャネルでこれを手伝ってくれました。

エラーの原因が発生した後にのみ要素がクラスと属性で更新されるため、コードにはsetTimeoutが必要です。

カスタムバインディング:

ko.bindingHandlers.validationSummary = {

    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
    },

    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

        var value = valueAccessor();
        value(); // register dependency

        function ValidationErrorModel(fieldRef, errorMessage) {
            this.fieldRef = ko.observable(fieldRef),
            this.errorMessage = ko.observable(errorMessage)
        }

        setTimeout(function() {
            var currentValidationModel = 
                $(".validationElement").map(function(i, elem) {
                    var $elem = $(elem);
                    return new ValidationErrorModel("#" + $elem.attr("name"), $elem.attr("title"));
                }).get();

            ko.bindingHandlers.foreach.update(element, function() { return currentValidationModel }, allBindingsAccessor, viewModel, bindingContext);
        }, 0);
    }
};

HTML:

<ul data-bind="validationSummary: errors">
    <li>
        <a data-bind="attr: { href: fieldRef }, text: errorMessage"></a>
    </li>
</ul>
于 2013-03-25T01:13:01.803 に答える