2012-11-28 19 views
5

Tôi đang cố gắng thử nghiệm và xem liệu có bất kỳ giải pháp thông minh nào để tạo trình xác thực tùy chỉnh có thể được tóm tắt để gọn gàng và sử dụng lại hay không.Xác nhận quan sátArray chống lại một điều kiện

Trong jsfiddle bên dưới, tôi chỉ cần đặt cùng một mô hình cha mẹ đơn giản lưu trữ và mảng các phép đo (chỉ là giá trị và ngày). Trong ví dụ này, tôi đưa ra hai yêu cầu.

  1. Mỗi phép đo có cả hai trường được cung cấp hoặc không được cung cấp.
  2. Phải có ít nhất một giá trị hợp lệ (đáp ứng điều kiện trước) trong mảng mẹ.

    Lý tưởng nhất, tôi muốn logic xác thực cho những gì xác định là hợp lệ, được lưu trữ trong đối tượng Đo lường như tôi đã thực hiện bên dưới. Nhưng, điều tôi rất bực mình là xác nhận "thực hành" mà tôi phải thực hiện trong mô hình gốc trong atLeastOne().

Xác nhận loại bỏ sẽ tự động xác thực trường riêng cho số và ngày NHƯNG, tôi phải bước vào và thực hiện xác thực đối với quy tắc cho mảng.

Câu hỏi: Có bất kỳ phương pháp nào cho phép tôi thiết lập tính hợp lệ KO để kiểm tra mảng cho điều kiện yêu cầu này trong khi vẫn có phương thức HasValues vẫn còn trong Mô hình đo không ??? Tức là tôi muốn trừu tượng khái niệm tìm kiếm "ít nhất một" thành trình xác thực tùy chỉnh của một số loại có thể xử lý công việc cho tôi, và sau đó chỉ cần nói cho trình xác nhận này "hey, đây là hàm tôi muốn bạn sử dụng để xác thực mỗi mục trong mảng. "

Cảm ơn trước!

function Model(data) 
    { 
     var self = this; 
     self.Measurements = ko.observableArray(); 

     for(var i = 0; i < data.length; i++) 
      self.Measurements.push(new Measurement(data[i])); 

     function hasAtLeastOne(){ 
      var atLeastOne = false; 
      $.each(self.Measurements(), function(i, item) { 
       if (item.HasValues()) { 
        atLeastOne = true; 
        return; 
       } 
      }); 
      return atLeastOne; 
     } 

     self.Save = function() {    
      if (self.canSave() && atLeastOne()) 
       alert('save'); 
      else 
       alert('arg!'); 
     }; 

     self.errors = ko.validation.group(self); 
     self.canSave = ko.computed(function() { 
      return self.errors().length == 0; 
     }); 
    } 

    function Measurement(data) 
    { 
     var self = this; 
     self.Value = ko.observable(data.val); 
     self.Date = ko.observable(data.date); 

     self.Value.extend({ required: { onlyIf: isRequired }, number: true }); 
     self.Date.extend({ required: { onlyIf: isRequired }, date: true }); 

     self.HasValues = function() { 
      return ko.utils.isNotNullUndefOrEmpty(self.Value()) && 
        self.Date() && self.Date().length > 0; 
     }; 

     function isRequired() { 
      return ko.utils.isNotNullUndefOrEmpty(self.Value()) || 
        (self.Date() && self.Date().length > 0); 
     } 
    } 

    ko.utils.isNotNullUndefOrEmpty = function (value) { 
     return (typeof value === 'string' && value.length > 0) || 
       (typeof value !== 'string' && value); 
    }; 

Đây là một jsfiddle để chơi với điều đó có ví dụ của tôi: http://jsfiddle.net/cACZ9/

Trả lời

7

Tôi đã được mucking xung quanh nguồn thư viện để xem nếu tôi có thể khám phá những điều đó sẽ là một lựa chọn khả thi. Đây là những gì tôi tìm thấy cho đến nay.

Hai tùy chọn khác nhau cả với những ưu/nhược điểm (tất nhiên):

Sử dụng Custom Validator:

ko.validation.rules['AtLeastOne'] = { 
     validator: function (array, predicate) { 
      var self = this; 
      self.predicate = predicate; 
      return ko.utils.arrayFirst(array, function (item) { 
       return self.predicate.call(item); 
      }) != null; 
     }, 
     message: 'The array must contain at least one valid element.' 
    }; 


    function Modal() { 
    var self = this; 
    self.Measurements = ko.observableArray().extend({ AtLeastOne: function() { 
     return this && this.HasValues(); 
    } 

    ...//refer to OP 
    ... 
    ... 

    self.Save() = function() { 
     if (self.errors().length == 0) 
      alert('Everything is valid, we can save!'); 
     else if (!self.Measurements.isValid()) 
      alert('You must have at least one valid item in the pot!'); 
    }; 
    }); 

Cách tiếp cận này khá nhiều mất xác nhận ra khỏi bàn tay của lập trình và rất thể tái sử dụng . Tuy nhiên, tôi nhận thấy rằng một trong những tiềm năng con là nó sẽ gọi quy tắc xác nhận tùy chỉnh mỗi khi bất kỳ giá trị được lưu trữ bên trong mảng (đối tượng hoặc cách khác) đã đột biến. Có thể không phải là vấn đề đối với hầu hết mọi người.

Sử dụng một nhà máy validator:

var KoValidationFactory = { 
     AtLeastOne: function (measurements, validator) { 
      return function() { 
       var self = this; 
       self.validator = validator; 
       return ko.utils.arrayFirst(measurements, function (measurement) { 
          return self.validator.call(measurement); 
         }) != null; 
      }; 
     } 

    }; 

    function Modal() { 
     var self = this; 
     self.Measurements = ko.observableArray(); 

    ...//refer to OP 
    ... 
    ... 

     self.Save = function() { 
      var atLeastOneArrayValidator = KoValidationFactory.AtLeastOne(self.Measurements(), function() { 
       return this && this.HasValues(); 
     }); 
      var arrayWasValid = atLeastOneArrayValidator(); 
      if (arrayWasValid && self.errors() == 0) 
      alert('everything is good, we can save'); 
      else if (!arrayWasValid) 
      alert('You must have at least one item in the pot!'); 
     }; 
    } 

Cách tiếp cận này có thể đảm bảo bạn chỉ xác nhận toàn bộ mảng khi bạn chắc chắn chọn làm như vậy. Down-side là bạn có nhiều công việc thực hành hơn và nó không tận dụng tối đa thư viện xác nhận loại bỏ. Bạn phải cụ thể là xác nhận mảng và bất kỳ/tất cả các quan sát khác mà có cách tiếp cận này mà có khả năng có thể trở nên lộn xộn nếu có nhiều người trong số họ.

Tôi khuyến khích chỉnh sửa và đề xuất về các phương pháp này.

Các vấn đề liên quan