2013-06-26 48 views
7

我使用的是Durandal,它反過來利用了Knockout。敲除驗證:動態約束

我希望能夠更改驗證動態長度

enter image description here

Fiddle

小提琴似乎表現比我的「工作」的解決方案略有不同,但它仍然沒有做我想要什麼/期待它。

視圖模型JS:

[嘗試1]

define(function() { 

    var self = this; 

    self.userInfo = {  
     IdOrPassportNumber: ko.observable().extend({ 
      required: true, 
      pattern: { 
       message: 'A message', 
       params: /some regex/ 
      } 
     }), 
     IdType: ko.observable() 
    }, 

    self.isIdValid = ko.validatedObservable({ 
     IdOrPassportNumber: self.userInfo.IdOrPassportNumber 
    }); 

    self.userInfo.IdOrPassportNumber.subscribe(function (value) { 
      if (isIdValid.isValid()) { 
       console.log('YOLO!'); 
      } 
    }); 

    self.userInfo.IdType.subscribe(function (value) { 
     console.log(value); 
     if (value === 'Passport') { 
      self.userInfo.IdOrPassportNumber.extend({ maxLength: 15 }); 
     } else { 
      self.userInfo.IdOrPassportNumber.extend({ maxLength: 13 }); 
     } 
    });  

    var viewModel = { 
     userInfo: self.userInfo 
    }; 

    viewModel["errors"] = ko.validation.group(viewModel.userInfo); 
    viewModel["errors"].showAllMessages(); 

    return viewModel; 
}); 

什麼似乎是發生的是,當我開始輸入我得到的13最大&分鐘驗證,但如果我繼續將驗證更改輸入到15.我嘗試了另一種方法,在最初可觀察的擴展EG中設置最大長度,緊接在正則表達式之後,然後將最小和最大長度設置爲使用可觀察值,直到不是成功。

[嘗試2]

self.userInfo = {  
     IdOrPassportNumber: ko.observable().extend({    
      maxLength: self.maxLength(), 
      minlength: self.maxLength() 
     }), 
     IdType: ko.observable() 
    }, 

    self.maxLength = ko.observable(); 

    self.userInfo.IdType.subscribe(function (value) { 

      if (value === 'Passport') { 
      self.maxLength(15) 
      } else { 
       self.maxLength(3) 
      } 
    }); 
+2

你可以使用http://cdnjs.com/來抓住淘汰賽驗證插件... – nemesv

+1

完成。 +1 Ps非常酷的網站。收藏確認:) –

回答

3

你是如此接近:-) 您必須提供observable本身,而不是解包值。因此,只需從maxLength()中刪除() - 驗證庫將自動爲您解包。

self.userInfo = {  
    IdOrPassportNumber: ko.observable().extend({    
     maxLength: self.maxLength, 
     minlength: self.maxLength 
    }), 
    IdType: ko.observable() 
}, 

下面是動態正則表達式模式的另一個例子。

zipPostalPattern = ko.pureComputed(() => this.countryCode() === 'US' ? '^\\d{5}(?:[-\\s]\\d{4})?$' : ''); 
    zipOrPostal: KnockoutObservable<string> = ko.observable('').extend(
    { 
     required: true, 
     pattern: { 
      message: 'This is not a valid postcode for the country', 
      params: this.zipPostalPattern 
     } 
    }); 

或(如果你不想要消息)。

zipPostalPattern = ko.pureComputed(function() { return this.countryCode() === 'US' ? '^\\d{5}(?:[-\\s]\\d{4})?$' : ''}); 
    zipOrPostal: KnockoutObservable<string> = ko.observable('').extend(
    { 
     required: true, 
     pattern: self.zipPostalPattern 
    }); 

重要:如果你不希望自定義消息不只是刪除message參數,並留下pattern = { params: this.zipPostalPattern },因爲它不會工作。如果您沒有消息,則必須直接爲pattern參數設置正則表達式/字符串。

或者當然你可以定義替代計算觀察到的(這裏叫countryCode()作爲函數的確定,因爲這是如何計算的工作)

zipOrPostal: KnockoutObservable<string> = ko.observable('').extend(
    { 
     required: true, 
     pattern: ko.pureComputed(function() { 
        return self.countryCode() === 'US' ? '^\\d{5}(?:[-\\s]\\d{4})?$' : '' 
        }) 
    }); 
+2

對於閱讀此內容的其他人。我無法測試這種情況與我在此階段的確切情況(不再在這個項目上)。我更喜歡@ Simon_Weaver的解決方案作爲公認的解決方案,並將其標記爲這樣。 –

+1

謝謝。我不得不說,今天我只能想到,我可能會將一個可觀測值作爲參數傳遞給一個規則,我非常興奮 - 然後意識到也許它可能不起作用 - 但是後來我再次興奮起來,似乎工作得很好:-)從我記得它沒有清楚的記錄,但是如果你已經知道如何使用Knockout並且增加了一些很好的靈活性,這很容易。 –

6

這裏是爲我工作溶液:

我利用了custom validation特徵的,更具體地 single use custom validation,因爲這不會被重複使用別處。

[嘗試3]

self.userInfo = {  
     IdOrPassportNumber: ko.observable().extend({ 
      required: true, 
      pattern: { 
       message: 'A message', 
       params: /some regex/ 
      }, 
      validation: { 
       validator: function (val) { 
        if (self.userInfo.IdType() === 'Id') { 
         return val.length === 13; 
        } else { 
         return val.length === 15; 
        } 
       }, 
       message: function() { 
        if (self.userInfo.IdType() === 'Id') { 
        return 'Required: 13 characters'; 
        } else { 
        return 'Required: 15 characters'; 
        } 
       } 
      } 
     }) 
    } 
+3

作爲一個方面說明。我注意到驗證順序也很重要,所以假設您希望您的自定義驗證程序(或任何其他)首先觸發,請相應地對其進行排序 –

+0

使用兩個不同的字段進行固定驗證和更改綁定在頁面上'?在保存時只需寫'var idOrPassword = id()|| password()'。 – blazkovicz

4

考慮這個

self.iDNumber = ko.observable('').extend({ 
     required: { 
      params: true, 
      message: 'ID Number is a required field.', 
      insertMessages: false 
     }, 
     SouthAfricanIDNumber: { 
      message: 'Please enter a valid South African ID number.', 
      onlyIf: function() { 
       return self.identityType() === 'SAID'; 
      } 
     } 
    }); 

其中SouthAfricanIDNumber是使用正則表達式定義驗證。

+1

歡迎來到SO :),但看到我接受的答案。 (我不再在這個項目上,但我會在將來記住它) –

+1

+1,以鼓勵他在第一篇文章中使用'間隔時間'。 – hirikarate