Angularjs dinamik ng-örüntü doğrulaması


84

Onay kutusu yanlışsa, ng-gerekli yönergeyi kullanarak bir metin girişi üzerinde doğrulamayı zorunlu kılan bir formum var. Onay kutusu doğruysa, alan gizlidir ve ng-gerekli değeri yanlış olarak ayarlanmıştır.

Sorun şu ki, girdide belirtilen doğrulama için bir regex'in yanı sıra ng-örüntü açısal yönergesini de kullanıyorum. Karşılaştığım sorun şu ki, bir kullanıcı geçersiz bir telefon numarası girerse, bu girişi devre dışı bırakmak için kutuyu işaretler (ve sonuç olarak başka bir doğrulamaya ihtiyaç duymaz), form, ng kalıbına göre geçersiz olduğu için gönderime izin vermez.

Giriş modelini boş olarak ayarlamak için bir ng-değiştirme işlevi ekleyerek bu sorunu çözmeye çalıştım, ancak ng-örüntüsü ve dolayısıyla alan, onay kutusunun ilk setinde hala geçersiz olarak ayarlandı. Bununla birlikte, kutunun işaretini kaldırırsam, her şeyi ilk form yüklemesine geri döndürürsem, ardından kutuyu tekrar işaretlersem, form geçerlidir ve gönderilebilir. Ne kaçırdığımdan emin değilim. Şimdiye kadar sahip olduğum ng-değiştirme kodu:

    var phoneNumberRegex = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
    $scope.phoneNumberPattern = phoneNumberRegex;
    $scope.removeValidation = function() {
        if ($scope.cell._newUser === false) {
            $scope.request._number = '';
            $scope.phoneNumberPattern = /[0-9a-zA-Z]?/;
        } else {
            $scope.phoneNumberPattern = phoneNumberRegex;
        }
    };

Yanıtlar:


175

Bu ilginç bir problem, karmaşık Açısal doğrulama. Aşağıdaki keman, istediğiniz şeyi gerçekleştirir:

http://jsfiddle.net/2G8gA/1/

Detaylar

rpatternAngular ng-requiredve ng-patternkodun bir karışımı olan yeni bir yönerge oluşturdum input[type=text]. Yaptığı şey required, alanın özniteliğini izlemek ve bunu regexp ile doğrulama yaparken dikkate almaktır, yani gerekli değilse alanı olarak işaretle valid-pattern.

Notlar

  • Kodun çoğu, bunun ihtiyaçlarına göre uyarlanmış Angular'dandır.
  • Onay kutusu işaretlendiğinde, alan gereklidir.
  • Gerekli onay kutusu yanlış olduğunda alan gizli değildir.
  • Demo için normal ifade basitleştirilmiştir (geçerli 3 rakamdır).

Bir kirli Yeni bir yönerge istemiyorsanız (ama daha küçük) çözümü, gibi bir şey olacaktır:

$scope.phoneNumberPattern = (function() {
    var regexp = /^\(?(\d{3})\)?[ .-]?(\d{3})[ .-]?(\d{4})$/;
    return {
        test: function(value) {
            if( $scope.requireTel === false ) {
                return true;
            }
            return regexp.test(value);
        }
    };
})();

Ve HTML'de herhangi bir değişiklik gerekmez:

<input type="text" ng-model="..." ng-required="requireTel"
    ng-pattern="phoneNumberPattern" />

Bu aslında , hesaba katmak yerine yöntemimizi çağırmak için açısal kandırıyor .test()RegExp.test()required


2
Fonksiyonu çevreleyen ve sonrasındaki yuvarlak parantezlerin ne işe yaradığını bilmek isterim. Onlar olmadan çalışmıyor
NeedHack

5
Fonksiyonu doğrudan çağırırlar ve dönüş değerini değişkene etkin bir şekilde yerleştirirler. Javascript'te, belirli bir bileşenin uygulama ayrıntılarıyla bir dış kapsamı kirletmemek çok yaygındır, örneğin modül modeline bakın .
Nikos Paraskevopoulos

6
AngularJS'de JS'nin "ördek yazımı" na dayalı bir numara oynamak için kirli çözüm, bugün gördüğüm en harika koddu. Gerçekten akıllı çözüm!
Florian Loch

Harika kod için teşekkürler, ancak yine de çok net değil, 1) docs.angularjs.org/api/ng/directive/input'a göre , "İfade bir RegExp nesnesi olarak değerlendirilirse, bu doğrudan kullanılır. İfade değerlendirilirse bir dizeye dönüştürülürse, bir RegExp "e dönüştürülecektir, ancak geri döndüğünde phoneNumberPattern bir nesne olabilir mi? Bunun bir Regxp Obj olması mı gerekiyor? 2) Ve testte depolanan fonksiyonda (değer) {}, "değer" parametresi nereden geliyor? Herhangi bir yanıt için teşekkür ederiz!
user2499325

1
1) "Ifade RegExp olarak değerlendirilirse" yan tümcesi, Angular tarafından, aldığı şeyin bir testyöntemi olup olmadığını kontrol ederek uygulanır . Bu nedenle, ona kendi özelliğimizle test(), esasen yerel JS'yi taklit eden bir nesne veriyoruz RegExp. 2) valueGerçek geçerlilik kontrolü yapılırken elbette Angular tarafından geçilir.
Nikos Paraskevopoulos

25

Nikos'un müthiş cevabından hiçbir şey almayarak, belki bunu daha basit bir şekilde yapabilirsiniz:

<form name="telForm">
  <input name="cb" type='checkbox' data-ng-modal='requireTel'>
  <input name="tel" type="text" ng-model="..." ng-if='requireTel' ng-pattern="phoneNumberPattern" required/>
  <button type="submit" ng-disabled="telForm.$invalid || telForm.$pristine">Submit</button>
</form>

İkinci girdiye dikkat edin: ng-ifFormlarda oluşturmayı ve doğrulamayı kontrol etmek için bir kullanabiliriz . Eğer requireTeldeğişken kaldırılırsa, ikinci giriş sadece gizlenemez, ancak tüm render olmaz, dolayısıyla form doğrulama geçecek ve butonu aktif hale geçecektir ve siz neye ihtiyacınız alırsınız.


1
Üst tarafı, basit. Bunun dezavantajı, ng-if ifadesi yanlış olduğunda kaldırılan herhangi bir girdinin, eğer ng-if daha sonra doğru olarak değerlendirilirse, bunların içindeki herhangi bir metin kaldırılacaktır. Yine de basitlik için +1.
Brad

Eklemek istedim, bu rotaya giderseniz, ng-if içindeki her şeyin (örneğin bir div üzerine koyarsanız) artık kendi kapsamına sahip olacağını anladığınızdan emin olun.
Brad

5

Kullanılan desen:

 ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"

Kullanılan referans dosyası:

 '<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>'

Giriş Örneği:

 <input type="number" require ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"><input type="submit">

2

 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.js"></script>
<input type="number" require ng-pattern="/^\d{0,9}(\.\d{1,9})?$/"><input type="submit">


2

Geçen gün bununla karşılaştım.

Yukarıdakinden daha kolay görünen şey, skop üzerindeki bir değişken üzerinde paterni ayarlamak ve görünümde ona ng-paterninde başvurmaktı.

"Onay kutusu işaretli olmadığında", sadece normal ifade değerini onChanged geri aramasında /.*/ olarak ayarlıyorum (eğer işaretlenmeyecekse). ng-deseni değişen ve "Tamam, değeriniz iyi" diyen seçer. Form artık geçerlidir. Ayrıca kötü verileri sahadan da kaldırırım, böylece orada oturan görünürde kötü bir telefon # olmaz.

Ng-gerekli ile ilgili ek sorunlar yaşadım ve aynı şeyi yaptım. Bir cazibe gibi çalıştı.


0

NgModel $ viewValue, öznitelik değerinde verilen Angular ifadeyi değerlendirerek bulunan bir RegExp ile eşleşmezse desen doğrulama hata anahtarını ayarlar. İfade bir RegExp nesnesi olarak değerlendirilirse, bu doğrudan kullanılır. İfade bir dize olarak değerlendirilirse, ^ ve $ karakterleri arasına kaydırıldıktan sonra bir RegExp'e dönüştürülür.

Görünüşe göre bu soruda en çok oylanan cevabın güncellenmesi gerekiyor, çünkü denediğimde testişlev uygulanmıyor ve doğrulama çalışmıyor.

Angular docs örneği benim için iyi çalışıyor:

Yerleşik doğrulayıcıları değiştirme

html

<form name="form" class="css-form" novalidate>
  <div>
   Overwritten Email:
   <input type="email" ng-model="myEmail" overwrite-email name="overwrittenEmail" />
   <span ng-show="form.overwrittenEmail.$error.email">This email format is invalid!</span><br>
   Model: {{myEmail}}
  </div>
</form>

js

var app = angular.module('form-example-modify-validators', []);

app.directive('overwriteEmail', function() {
    var EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@example\.com$/i;

    return {
        require: 'ngModel',
        restrict: '',
        link: function(scope, elm, attrs, ctrl) {
            // only apply the validator if ngModel is present and Angular has added the email validator
            if (ctrl && ctrl.$validators.email) {

                // this will overwrite the default Angular email validator
                ctrl.$validators.email = function(modelValue) {
                    return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue);
                };
             }
         }
     };
 });

Plunker


-1

Bazı ülkeler için kendi özel modelinizi oluşturmak için https://regex101.com/ sitesini kullanabilirsiniz :

Örneğin, Polonya:

-pattern = xxxxxxxxx OR xxx-xxx-xxx OR xxx xxx xxx 
-regexp ="^\d{9}|^\d{3}-\d{3}-\d{3}|^\d{3}\s\d{3}\s\d{3}"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.