2012-10-12 11 views
51

मुझे लगता है कि एक सहेजें बटन उदाहरण से लिया शामिल एक कोणीय एप्लिकेशन है:, उपयोगकर्ता के रूप में समस्याओं को ठीक करता है क्योंकि form.$invalid झूठा हो जाता हैAngularJS: सर्वर साइड सत्यापन के साथ एकीकृत करने

<button ng-click="save" ng-disabled="form.$invalid">SAVE</button> 

इस ग्राहक साइड सत्यापन के लिए महान काम करता है लेकिन मेरे पास एक ईमेल फ़ील्ड है जो अमान्य सेट है यदि कोई अन्य उपयोगकर्ता एक ही ईमेल के साथ पंजीकृत है।

जैसे ही मैं अपना ईमेल फ़ील्ड अमान्य सेट करता हूं, मैं फॉर्म सबमिट नहीं कर सकता, और उपयोगकर्ता के पास उस सत्यापन त्रुटि को ठीक करने का कोई तरीका नहीं है। तो अब मैं अपने सबमिट बटन को अक्षम करने के लिए form.$invalid का उपयोग नहीं कर सकता।

एक बेहतर तरीका

उत्तर

27

मुझे कुछ परियोजनाओं में इसकी आवश्यकता है इसलिए मैंने एक निर्देश बनाया। आखिर में गिटहब पर डालने के लिए एक पल लिया जो ड्रॉप-इन समाधान चाहता है।

https://github.com/webadvanced/ng-remote-validate

विशेषताएं: किसी भी पाठ या पासवर्ड इनपुट सत्यापन और टैक्सी में Angulars साथ

  • निर्माण निर्माण के अजाक्स सत्यापन के लिए समाधान में

    • ड्रॉप चले पर पहुंचा जा। inputName। $ error.ngRemoteValidate

    • सर्वर अनुरोध (डिफ़ॉल्ट 400 मि.से) थ्रॉटल्स और ng-remote-throttle="550"

    • साथ सेट किया जा सकता की अनुमति देता है HTTP विधि परिभाषा (डिफ़ॉल्ट पोस्ट) दर्ज करने के लिए उपयोगकर्ता की आवश्यकता है कि एक परिवर्तन पासवर्ड फार्म के लिए ng-remote-method="GET"

    उदाहरण उपयोग के साथ अपने वर्तमान पासवर्ड के साथ ही नया पासवर्ड .:

    <h3>Change password</h3> 
    <form name="changePasswordForm"> 
        <label for="currentPassword">Current</label> 
        <input type="password" 
          name="currentPassword" 
          placeholder="Current password" 
          ng-model="password.current" 
          ng-remote-validate="/customer/validpassword" 
          required> 
        <span ng-show="changePasswordForm.currentPassword.$error.required && changePasswordForm.confirmPassword.$dirty"> 
         Required 
        </span> 
        <span ng-show="changePasswordForm.currentPassword.$error.ngRemoteValidate"> 
         Incorrect current password. Please enter your current account password. 
        </span> 
    
        <label for="newPassword">New</label> 
        <input type="password" 
          name="newPassword" 
          placeholder="New password" 
          ng-model="password.new" 
          required> 
    
        <label for="confirmPassword">Confirm</label> 
        <input ng-disabled="" 
          type="password" 
          name="confirmPassword" 
          placeholder="Confirm password" 
          ng-model="password.confirm" 
          ng-match="password.new" 
          required> 
        <span ng-show="changePasswordForm.confirmPassword.$error.match"> 
         New and confirm do not match 
        </span> 
    
        <div> 
         <button type="submit" 
           ng-disabled="changePasswordForm.$invalid" 
           ng-click="changePassword(password.new, changePasswordForm);reset();"> 
          Change password 
         </button> 
        </div> 
    </form> 
    
  • +0

    यह बहुत अच्छा काम करता है! मैं संस्करण 0.6.1 का उपयोग कर रहा हूं, मुझे लगता है कि 'inputnameSetArgs' का उपयोग करके एक खुला मुद्दा नहीं है। और दायरे में '$ पैरेंट 'जोड़ने का एक फिक्स। मैंने इसे मैन्युअल रूप से बदल दिया और फिर 'SetArgs' को सर्वर पर भेजे गए अतिरिक्त पैरामीटर के साथ बुलाया जाता है। – Guus

    +0

    पूरी तरह से काम करता है, आपके साझाकरण के लिए धन्यवाद! –

    73

    यह एक और मामले में जहां एक कस्टम निर्देश अपने दोस्त है वहाँ होना चाहिए। जब आप सत्यापन कर रहे हों तो सर्वर पर कॉल करने के लिए आप एक निर्देश बनाना और $ http या $ संसाधन इंजेक्ट करना चाहते हैं।

    कस्टम निर्देश के लिए कुछ छद्म कोड:

    <input type="email" ng-model="userEmail" name="userEmail" required unique-email/> 
    <span ng-show="myFormName.userEmail.$error.uniqueEmail">Email is not unique.</span> 
    

    संपादित करें:

    app.directive('uniqueEmail', function($http) { 
        var toId; 
        return { 
        restrict: 'A', 
        require: 'ngModel', 
        link: function(scope, elem, attr, ctrl) { 
         //when the scope changes, check the email. 
         scope.$watch(attr.ngModel, function(value) { 
         // if there was a previous attempt, stop it. 
         if(toId) clearTimeout(toId); 
    
         // start a new attempt with a delay to keep it from 
         // getting too "chatty". 
         toId = setTimeout(function(){ 
          // call to some API that returns { isValid: true } or { isValid: false } 
          $http.get('/Is/My/EmailValid?email=' + value).success(function(data) { 
    
           //set the validity of the field 
           ctrl.$setValidity('uniqueEmail', data.isValid); 
          }); 
         }, 200); 
         }) 
        } 
        } 
    }); 
    

    और यहाँ कैसे आप ऊपर निशान में यह उपयोग करेंगे ऊपर क्या हो रहा है की एक छोटी विवरण।

    1. जब आप इनपुट में मान अपडेट करें, यह अद्यतन करता है $ scope.userEmail
    2. निर्देश यह की स्थापना में यह समारोह लिंक कर रहा है $ scope.userEmail पर एक $ घड़ी है।
      • जब $ घड़ी शुरू हो रहा है यह $ http ajax कॉल के माध्यम से सर्वर को फोन करेगा, ईमेल
      • सर्वर ईमेल पते की जांच और इस तरह 'एक सरल प्रतिक्रिया वापसी होगी {अगर है: सच} गुजर
      • कि प्रतिक्रिया $ नियंत्रण के लिए उपयोग की जाती है नियंत्रण की वैधता।
    3. एनजी-शो सेट के साथ मार्कअप में केवल एक ही दिखाया गया है जब अद्वितीय ईमेल वैधता स्थिति गलत है।

    ... उपयोगकर्ता मतलब यह है कि करने के लिए:

    1. प्रकार ईमेल।
    2. मामूली विराम।
    3. ईमेल ईमेल अद्वितीय नहीं है, तो "ईमेल अद्वितीय नहीं है" संदेश प्रदर्शित करता है "वास्तविक समय"।

    EDIT2: यह आपको फ़ॉर्म का उपयोग करने की अनुमति भी देता है। $ सबमिट सबमिट करने के लिए अमान्य $।

    +1

    लेकिन यह वास्तव में मेरी समस्या का समाधान नहीं करता है। वे अभी भी संभावित रूप से एक गैर-अद्वितीय ईमेल सबमिट कर सकते हैं और मुझे अभी भी सर्वर पक्ष पर इसे सत्यापित करना होगा, जिस बिंदु पर मुझे अभी भी क्लाइंटसाइड त्रुटि दिखाई देनी चाहिए, न कि इस निर्देश के माध्यम से? – mkoryak

    +0

    लेकिन अगर मैं एक अमान्य ईमेल जमा करने में सक्षम हूं, तो मैं digress, सबमिट एक त्रुटि वापस कर देगा और अवैध रूप से चिह्नित फॉर्म, इस बिंदु पर उन्हें फॉर्म को – mkoryak

    +0

    सबमिट करने से पहले ईमेल फ़ील्ड को वैध चिह्नित करने के लिए इस निर्देश का उपयोग करने के लिए मजबूर किया जाएगा। यह निर्देश सर्वर पर असीमित रूप से एक अनुरोध भेजेगा, जो ईमेल की जांच करेगा और कहेंगे कि यह अद्वितीय है या नहीं, सर्वर के पक्ष में ... यदि यह एक सत्यापन संदेश नहीं दिखाया जाएगा। –

    16

    मैंने समाधान के साथ प्लंकर बनाया है जो मेरे लिए सही काम करता है। यह कस्टम निर्देश का उपयोग करता है लेकिन पूरे रूप में और एकल फ़ील्ड पर नहीं।

    http://plnkr.co/edit/HnF90JOYaz47r8zaH5JY

    मैं सर्वर सत्यापन के लिए सबमिट बटन को निष्क्रिय करने की सिफारिश नहीं होगा।

    +3

    यह बेहद सहायक है! मुझे एक बदलाव करना पड़ा: नवीनतम संस्करणों में कोणीय नहीं है। प्रत्येक के लिए, इसलिए मैंने इसे $ .each का उपयोग करने के लिए अपडेट किया: http://plnkr.co/edit/1UNljzvr70F6O6Tac1R8 – jphoward

    +1

    मुझे इस प्लंकर अपडेट को चलाने के लिए परेशानी हो रही है (jphoward) बनाया गया। कोणीय का कौन सा संस्करण प्रत्येक के लिए समर्थन नहीं करता है? मैं देखता हूं कि आपने "1.1.1" शामिल किया है। –

    5

    ठीक है।मामले में अगर कोई काम कर रहे संस्करण की जरूरत है, यह यहाँ है:

    डॉक से:

    $apply() is used to enter Angular execution context from JavaScript 
    
    (Keep in mind that in most places (controllers, services) 
    $apply has already been called for you by the directive which is handling the event.) 
    

    यह बनाया मुझे लगता है कि हम की जरूरत नहीं है: $scope.$apply(function(s) { अन्यथा इसके बारे में $digest

    app.directive('uniqueName', function($http) { 
        var toId; 
        return { 
         require: 'ngModel', 
         link: function(scope, elem, attr, ctrl) { 
          //when the scope changes, check the name. 
          scope.$watch(attr.ngModel, function(value) { 
           // if there was a previous attempt, stop it. 
           if(toId) clearTimeout(toId); 
    
           // start a new attempt with a delay to keep it from 
           // getting too "chatty". 
           toId = setTimeout(function(){ 
            // call to some API that returns { isValid: true } or { isValid: false } 
            $http.get('/rest/isUerExist/' + value).success(function(data) { 
    
             //set the validity of the field 
             if (data == "true") { 
              ctrl.$setValidity('uniqueName', false); 
             } else if (data == "false") { 
              ctrl.$setValidity('uniqueName', true); 
             } 
            }).error(function(data, status, headers, config) { 
             console.log("something wrong") 
            }); 
           }, 200); 
          }) 
         } 
        } 
    }); 
    

    शिकायत एचटीएमएल:

    <div ng-controller="UniqueFormController"> 
    
         <form name="uniqueNameForm" novalidate ng-submit="submitForm()"> 
    
          <label name="name"></label> 
          <input type="text" ng-model="name" name="name" unique-name> <!-- 'unique-name' because of the name-convention --> 
    
          <span ng-show="uniqueNameForm.name.$error.uniqueName">Name is not unique.</span> 
    
          <input type="submit"> 
         </form> 
        </div> 
    

    नियंत्रक इस तरह दिख सकता है:

    app.controller("UniqueFormController", function($scope) { 
        $scope.name = "Bob" 
    }) 
    
    +0

    मैं इसे सेटटाइमआउट –

    +0

    @ses के बजाय कोणीय [$ टाइमआउट] (https://docs.angularjs.org/api/ng/service/$timeout) का उपयोग करने के लिए बदल दूंगा: यह ठीक है, ठीक है! बस इसे ऑनब्लर, या बदले में कॉल करना चाहते हैं। क्या यह संभव है? क्या यह सही तरीका है? – VBMali

    2

    इस पेज से जवाब के लिए धन्यवाद के बारे में https://github.com/webadvanced/ng-remote-validate

    सीखा

    विकल्प निर्देश, जो वास्तव में पसंद नहीं करते हैं, उससे थोड़ा कम है, क्योंकि प्रत्येक फ़ील्ड निर्देश लिखने के लिए है। मॉड्यूल समान है - एक सार्वभौमिक समाधान।

    लेकिन मॉड्यूल में मुझे कुछ याद आ रहा था - कई नियमों के लिए फ़ील्ड की जांच करें।
    फिर मैंने मॉड्यूल को संशोधित किया https://github.com/borodatych/ngRemoteValidate
    रूसी रीडमे के लिए माफी, अंततः बदल जाएगी।
    मुझे अचानक साझा करने के लिए जल्द ही एक ही समस्या है।
    हां, और हम इसके लिए यहां एकत्र हुए हैं ...

    लोड:

    <script type="text/javascript" src="../your/path/remoteValidate.js"></script> 
    

    को शामिल करें:

    var app = angular.module('myApp', [ 'remoteValidate' ]); 
    

    एचटीएमएल

    <input type="text" name="login" 
    ng-model="user.login" 
    remote-validate="('/ajax/validation/login', ['not_empty',['min_length',2],['max_length',32],'domain','unique'])" 
    required 
    /> 
    <br/> 
    <div class="form-input-valid" ng-show="form.login.$pristine || (form.login.$dirty && rv.login.$valid)"> 
        From 2 to 16 characters (numbers, letters and hyphens) 
    </div> 
    <span class="form-input-valid error" ng-show="form.login.$error.remoteValidate"> 
        <span ng:bind="form.login.$message"></span> 
    </span> 
    

    बैकएंड [Kohana]

    public function action_validation(){ 
    
        $field = $this->request->param('field'); 
        $value = Arr::get($_POST,'value'); 
        $rules = Arr::get($_POST,'rules',[]); 
    
        $aValid[$field] = $value; 
        $validation = Validation::factory($aValid); 
        foreach($rules AS $rule){ 
         if(in_array($rule,['unique'])){ 
          /// Clients - Users Models 
          $validation = $validation->rule($field,$rule,[':field',':value','Clients']); 
         } 
         elseif(is_array($rule)){ /// min_length, max_length 
          $validation = $validation->rule($field,$rule[0],[':value',$rule[1]]); 
         } 
         else{ 
          $validation = $validation->rule($field,$rule); 
         } 
        } 
    
        $c = false; 
        try{ 
         $c = $validation->check(); 
        } 
        catch(Exception $e){ 
         $err = $e->getMessage(); 
         Response::jEcho($err); 
        } 
    
        if($c){ 
         $response = [ 
          'isValid' => TRUE, 
          'message' => 'GOOD' 
         ]; 
        } 
        else{ 
         $e = $validation->errors('validation'); 
         $response = [ 
          'isValid' => FALSE, 
          'message' => $e[$field] 
         ]; 
        } 
        Response::jEcho($response); 
    } 
    
    संबंधित मुद्दे