2013-03-24 84 views
2

我想創建一個驗證摘要,其中包含指向KnockoutJS Validation Library錯誤的鏈接列表,我需要創建一個自定義foreach處理程序來呈現它。Knockout自定義綁定foreach

使用下面的代碼我試圖實現的是能夠聽取錯誤()列表中的更改並構造驗證摘要。我實際上並沒有使用「錯誤」列表(因爲它只是一個字符串列表),而是使用它來監聽更改。 (somewhat related)我有一個範圍錯誤 - 如在「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> 

回答

2

#1用戶@antishok幫我這個在#knockoutjs IRC頻道:

該代碼需要一個setTimeout,因爲元素只有在對錯誤進行求和後纔會用類和屬性進行更新d

自定義綁定:

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>