एक निर्देश का उपयोग करके AngularJS ब्राउज़र ऑटोफ़िल वर्कअराउंड


111

AngularJS में फ़ॉर्म सबमिट करते समय और ब्राउज़र का उपयोग पासवर्ड कार्यक्षमता याद रखें, और बाद के लॉगिन प्रयास में आपने ब्राउज़र को उपयोगकर्ता नाम और पासवर्ड के साथ लॉगिन फ़ॉर्म में भरने दिया, $scopeमॉडल ऑटोफिल के आधार पर बदला नहीं जाएगा।

केवल गंदा हैक मैंने पाया है कि निम्नलिखित निर्देश का उपयोग करें:

app.directive("xsInputSync", ["$timeout" , function($timeout) {
    return {
        restrict : "A",
        require: "?ngModel",
        link : function(scope, element, attrs, ngModel) {
            $timeout(function() {
                if (ngModel.$viewValue && ngModel.$viewValue !== element.val()) {
                    scope.apply(function() {
                        ngModel.$setViewValue(element.val());
                    });
                }
                console.log(scope);
                console.log(ngModel.$name);
                console.log(scope[ngModel.$name]);
            }, 3000);
        }
    };
}]);

समस्या यह है कि ngModel.$setViewValue(element.val());बदले हुए element.val()मूल्य के आधार पर न तो मॉडल बदलता है और न ही दृश्य । मैं इसे कैसे पूरा कर सकता हूं?


यह कोड पहले ब्लश पर ठीक लगता है ... लेकिन बाकी (मार्कअप, आदि) कहां है? क्या आपके पास एक बेला या डुबकी है जिसे हम देख सकते हैं?
बेन लेश

यहाँ प्लंक है : plnkr.co/edit/CHrBAVU9Ycl2ex2DRr6R मुझे यकीन नहीं है कि यह सीधे प्लंकर पर काम करता है क्योंकि यह एक आइफ्रेम में चलता है।
लुकासप

1
आपको गुंजाइश की आवश्यकता नहीं है। $ कोणीय के $ टाइमआउट के अंदर लागू करें। आपको इसे मूल window.setTimeout के अंदर की आवश्यकता हो सकती है। लेकिन कोणीय के एक का उपयोग करना बेहतर विचार है।
gorpacrate

1
इस समस्या के लिए कोणीय देव tbosch से एक "आधिकारिक" पॉलीफिल फिक्स है। कृपया नीचे दिए गए उत्तर stackoverflow.com/a/25687396/3009639 में विवरण देखें।
orzzaczky

दुर्भाग्य से "आधिकारिक" फिक्स परित्याग है और कई ब्राउज़रों में काम नहीं करता है। मुद्दे दायर किए गए हैं, लेकिन संबोधित नहीं किए गए हैं ताकि खोज जारी रहे ...
साइबरवॉम्बट

जवाबों:


45

स्पष्ट रूप से यह कोणीय के साथ एक ज्ञात मुद्दा है और वर्तमान में खुला है

मुझे यकीन नहीं है कि आप यहाँ क्या कर सकते हैं इसके अलावा किसी तरह का काम कर रहे हैं जैसे आप कोशिश कर रहे हैं। ऐसा लगता है कि आप सही रास्ते पर हैं। मैं अपने ब्राउज़र को आपके प्लंक के लिए पासवर्ड याद रखने की कोशिश करने के लिए नहीं मिला, इसलिए मुझे यकीन नहीं है कि यह काम करेगा लेकिन एक नज़र:

app.directive('autoFillSync', function($timeout) {
   return {
      require: 'ngModel',
      link: function(scope, elem, attrs, ngModel) {
          var origVal = elem.val();
          $timeout(function () {
              var newVal = elem.val();
              if(ngModel.$pristine && origVal !== newVal) {
                  ngModel.$setViewValue(newVal);
              }
          }, 500);
      }
   }
});
<form name="myForm" ng-submit="login()">
   <label for="username">Username</label>
   <input type="text" id="username" name="username" ng-model="username" auto-fill-sync/><br/>
   <label for="password">Password</label>
   <input type="password" id="password" name="password" ng-model="password" auto-fill-sync/><br/>
   <button type="submit">Login</button>
</form>

मुझे लगता है कि आपको अपने दृष्टिकोण को थोड़ा सरल बनाने की आवश्यकता है। एक चीज जो मैं निश्चित रूप से सुझाता हूं वह ngModel.$pristineयह है कि आप यह सुनिश्चित करें कि आप कुछ गरीब उपयोगकर्ता के इनपुट को अधिलेखित नहीं कर रहे हैं। इसके अलावा, 3 सेकंड शायद बहुत लंबा है। आपको $ timeout, BTW में $ apply () कॉल नहीं करना चाहिए, यह स्वचालित रूप से आपके लिए $ डाइजेस्ट को कतारबद्ध करना चाहिए।

असली पकड़: क्या आपका ब्राउज़र निष्पादन के लिए कोणीय को हरा देगा? मेरे ब्राउज़र के बारे में क्या?

यह संभवतः एक अकल्पनीय युद्ध है, यही वजह है कि एंगुलर (या नॉकआउट) इसे आसानी से हल करने में सक्षम नहीं है। निर्देश के प्रारंभिक निष्पादन के समय आपके इनपुट में डेटा की स्थिति की कोई गारंटी नहीं है। कोणीय के प्रारंभ के समय भी नहीं .... इसलिए इसे हल करने के लिए एक मुश्किल समस्या है।


1
$ प्रिस्टाइन के बारे में अच्छी बात। खैर, 3 सेकंड के परीक्षण के प्रयोजनों के लिए वहाँ है। "पासवर्ड सहेजें" संवाद सफारी पर काम करता है। यह एक और मुद्दा है जिसकी मुझे जांच करनी है।
लुकासप

बस उसे स्थानीय भंडारण के साथ बेवकूफ बनाओ। :) ... मैं इसके बारे में सोचता रहूँगा। लेकिन मुझे किसी भी दो-तरफ़ा बाइंडिंग के साथ ऑटोफ़िल काम करने की व्यवहार्यता के बारे में मेरा संदेह है।
बेन लेश

हां, लेकिन मुझे अभी भी इसे काम करने के लिए एक निर्देश से मॉडल को अपडेट करने में सक्षम होना चाहिए।
लुकासप

1
मैं लोकलस्टोरेज के बारे में मजाक कर रहा था, आप वहां पासवर्ड नहीं रखना चाहेंगे।
बेन लेश

1
यह सफारी और क्रेडिट कार्ड ऑटोफिल के साथ काम नहीं करेगा, क्योंकि यह ऑटोफिल उपयोगकर्ता द्वारा किसी भी समय चालू हो जाता है
डलास क्लार्क

35

यहाँ एक समाधान है जो प्रस्तुत किए गए अन्य समाधानों की तुलना में बहुत कम है और शब्दार्थ है ध्वनि AngularJS: http://victorblog.com/2014/01/12/fixing-autocomplete-autofill-on-angularjs-form-submit/

myApp.directive('formAutofillFix', function() {
  return function(scope, elem, attrs) {
    // Fixes Chrome bug: https://groups.google.com/forum/#!topic/angular/6NlucSskQjY
    elem.prop('method', 'POST');

    // Fix autofill issues where Angular doesn't know about autofilled inputs
    if(attrs.ngSubmit) {
      setTimeout(function() {
        elem.unbind('submit').submit(function(e) {
          e.preventDefault();
          elem.find('input, textarea, select').trigger('input').trigger('change').trigger('keydown');
          scope.$apply(attrs.ngSubmit);
        });
      }, 0);
    }
  };
});

फिर आप बस अपने फॉर्म में निर्देश संलग्न करें:

<form ng-submit="submitLoginForm()" form-autofill-fix>
  <div>
    <input type="email" ng-model="email" ng-required />
    <input type="password" ng-model="password" ng-required />
    <button type="submit">Log In</button>
  </div>
</form>

2
यह एक काम किया। हमने बिना किसी परिणाम के सबसे ऊपर की कोशिश की। धन्यवाद!!! परिणाम mobbr.com
पैट्रिक सैवेल

1
जैसा कि यह jQuery का उपयोग करता है, यह jQuery के बिना काम करने की उम्मीद नहीं है।
क्विन स्ट्राल

1
यहां हम 2018 में हैं और यह अभी भी ठीक है। धन्यवाद ईजेकील!
स्कॉट मैनी

35

आप $timeoutइस तरह एक या कुछ भी उपयोग करने की जरूरत नहीं है । आप एक ईवेंट सिस्टम का उपयोग कर सकते हैं।

मुझे लगता है कि यह अधिक Angularish है और jQuery या कस्टम ईवेंट पकड़ने पर निर्भर नहीं करता है।

अपने सबमिट हैंडलर पर उदाहरण के लिए:

$scope.doLogin = function() {
    $scope.$broadcast("autofill:update");

    // Continue with the login.....
};

और तब आपके पास autofillइस तरह का एक निर्देश हो सकता है :

.directive("autofill", function () {
    return {
        require: "ngModel",
        link: function (scope, element, attrs, ngModel) {
            scope.$on("autofill:update", function() {
                ngModel.$setViewValue(element.val());
            });
        }
    }
});

अंत में, आपका HTML निम्न होगा:

<input type="text" name="username" ng-model="user.id" autofill="autofill"/>

14
मेरे मामले में सबमिट बटन अक्षम है जबकि इनपुट खाली हैं।
गोरक्षपीठ

4
क्या आपको कभी इससे कोई परेशानी नहीं है क्योंकि यह एसिंक्रोनस है? जहां ईवेंट को दोहराने से पहले सर्वर पर लॉगिन कॉल पहले से ही छोड़ दिया गया था और निर्देश के पास गुंजाइश अपडेट करने का समय था?
सेंडर

12

अब हैक करने की कोई जरूरत नहीं है! कोणीय देव tbosch ने एक पॉलीफ़िल बनाया जो एक परिवर्तन ईवेंट को ट्रिगर करता है जब ब्राउज़र एक परिवर्तन ईवेंट को ट्रिगर किए बिना फ़ील्ड बदलता है:

https://github.com/tbosch/autofill-event

अभी के लिए वे इसे कोणीय कोड में नहीं बनाएंगे, क्योंकि यह ब्राउज़र के लिए एक बगिफ़ है, और यह भी बिना कोणीय के काम करता है (जैसे कि सादे jQuery के ऐप्स के लिए)।

"पॉलीफ़िल दस्तावेज़ लोड पर परिवर्तन के लिए जांच करेगा और यह भी कि जब एक इनपुट छोड़ा जाता है (केवल उसी रूप में)। हालांकि, यदि आप चाहते हैं तो आप मैन्युअल रूप से चेक को ट्रिगर कर सकते हैं।

परियोजना में इकाई परीक्षण के साथ-साथ अर्ध स्वचालित परीक्षण भी हैं, इसलिए हमारे पास आवश्यक ब्राउज़र सेटिंग्स के साथ सभी अलग-अलग उपयोग के मामले को इकट्ठा करने के लिए अंत में एक जगह है।

कृपया ध्यान दें: यह पॉलीफ़िल सादे AngularJS ऐप्स के साथ, AngularJS / jQuery ऐप्स के साथ लेकिन सादे jQuery ऐप्स के साथ भी काम करती है जो Angular का उपयोग नहीं करते हैं। "

इसके साथ स्थापित किया जा सकता है:

bower install autofill-event --save

अपने पेज में jQuery या कोणीय के autofill-event.js बाद स्क्रिप्ट जोड़ें ।

यह निम्न कार्य करेगा:

  • DOMContentLoaded के बाद: सभी इनपुट फ़ील्ड की जाँच करें
  • एक फ़ील्ड छोड़ दिया गया है: उसी रूप में अन्य सभी फ़ील्ड जांचें

एपीआई (चेक को मैन्युअल रूप से ट्रिगर करने के लिए):

  • $el.checkAndTriggerAutoFillEvent(): दिए गए jQuery / jQLite तत्व में सभी DOM तत्वों के लिए जाँच निष्पादित करें।

यह काम किस प्रकार करता है

  1. उपयोगकर्ता द्वारा इनपुट तत्वों के सभी परिवर्तनों को याद रखें (परिवर्तन की घटनाओं को सुनकर) और जावास्क्रिप्ट द्वारा (jQuery / jQLite तत्वों के लिए $ el.val () को इंटरसेप्ट करके)। उस बदले हुए मूल्य को एक निजी संपत्ति में तत्व पर संग्रहीत किया जाता है।

  2. ऑटो भरण के लिए एक तत्व की जांच करना: याद किए गए मूल्य के साथ तत्व के वर्तमान मूल्य की तुलना करें। यदि यह अलग है, तो एक परिवर्तन ईवेंट ट्रिगर करें।

निर्भरता

AngularJS या jQuery (एक या दोनों के साथ काम करता है)

अधिक जानकारी और स्रोत github पृष्ठ पर

जीथब पर मूल कोणीय अंक # 1460 यहां पढ़ा जा सकता है।


2
यह मेरे मामलों के लिए काम नहीं करता है। checkAndTriggerAutoFillEvent () ट्रिगर है और घटनाओं को उत्पन्न करता है, लेकिन AngularJS कभी भी अपने मॉडल को अपडेट नहीं करता है और सोचता है कि फ़ील्ड खाली हैं।
Splaktar

मुझे इस पॉलिल के उपयोग से कोई समस्या नहीं है। यदि आप इसे ठीक से काम करने के लिए नहीं प्राप्त कर सकते हैं, तो आपको कुछ कोड सहित एक अलग प्रश्न बनाना चाहिए। यदि आपको एक बग मिल जाता है, तो आपको जीथब पर टिकटों की जांच करनी चाहिए, या एक नया खोलना चाहिए।
orzzaczky

हां, मुझे लगता है कि यह इस बग से संबंधित है: github.com/tbosch/autofill-event/issues/11
Splaktar

1
ngModelOptionsके साथ संयुक्त autofill-eventमतलब है कि आप अब अपने मॉडल को सही ढंग से सिंक करने के लिए सुनिश्चित करने changeके लिए updateOnघटनाओं में से एक के रूप में निर्दिष्ट कर सकते हैं ।
मॉरलोक

10

डर्टी कोड, जांच करें कि क्या इस कोड का उपयोग करने से पहले https://github.com/angular/angular.js/issues/1460#issuecomment-18572604 जारी किया गया है। यह निर्देश उन घटनाओं को ट्रिगर करता है जब फ़ील्ड भरा जाता है, न केवल सबमिट करने से पहले (यह आवश्यक है कि आपको सबमिट करने से पहले इनपुट को संभालना है)

 .directive('autoFillableField', function() {
    return {
                   restrict: "A",
                   require: "?ngModel",
                   link: function(scope, element, attrs, ngModel) {
                       setInterval(function() {
                           var prev_val = '';
                           if (!angular.isUndefined(attrs.xAutoFillPrevVal)) {
                               prev_val = attrs.xAutoFillPrevVal;
                           }
                           if (element.val()!=prev_val) {
                               if (!angular.isUndefined(ngModel)) {
                                   if (!(element.val()=='' && ngModel.$pristine)) {
                                       attrs.xAutoFillPrevVal = element.val();
                                       scope.$apply(function() {
                                           ngModel.$setViewValue(element.val());
                                       });
                                   }
                               }
                               else {
                                   element.trigger('input');
                                   element.trigger('change');
                                   element.trigger('keyup');
                                   attrs.xAutoFillPrevVal = element.val();
                               }
                           }
                       }, 300);
                   }
               };
});

5

स्पष्ट सीधे आगे समाधान की तरह लगता है। कोई jQuery की जरूरत है।

अपडेट करें:

  • मॉडल केवल तभी अपडेट किया जाता है जब मॉडल मूल्य वास्तविक इनपुट मूल्य के बराबर नहीं होता है।
  • चेकिंग पहले ऑटोफिल पर नहीं रुकती है। यदि आप उदाहरण के लिए किसी अन्य खाते का उपयोग करना चाहते हैं तो।

app.directive('autofillable', ['$timeout', function ($timeout) {
    return {
        scope: true,
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {
            scope.check = function(){
                var val = elem[0].value;
                if(ctrl.$viewValue !== val){
                    ctrl.$setViewValue(val)
                }
                $timeout(scope.check, 300);
            };
            scope.check();
        }
    }
}]);

4
+1 अच्छा समाधान, जो मैं आया था, उसके समान। इसके अलावा मैं सुझाव दूंगा कि पहले यह जांचा जाए कि क्या मॉडल $pristineइसे बदलने से पहले है, और फिर इसे बदलने के बाद इसे चालू रखें $pristine। अन्यथा आप पाएंगे कि यदि कोई ऑटोफ़िल डेटा के साथ कोई फ़ॉर्म लोड किया गया है, तो उपरोक्त निर्देश अभी भी मॉडल को अपडेट करेगा और बाद में dirtyभी इसे बनाएगा , हालांकि फॉर्म नियंत्रण को अभी भी अछूता माना जाना चाहिए। अपने निर्देशन का उपयोग करते हुए यहां उदाहरण दें। मैंने उस कोड की टिप्पणी की है जो मैं इसमें
जोड़ूंगा

1
इसके अलावा, मुझे लगता है कि scope:trueहोना चाहिएscope:{}
OACDesigns

4

समाधान 1 [$ समय का उपयोग करके]:

निर्देशक:

app.directive('autoFillSync', function($timeout) {
    return {
      require: 'ngModel',
      link: function(scope, elem, attrs, model) {
          var origVal = elem.val();
          $timeout(function () {
              var newVal = elem.val();
              if(model.$pristine && origVal !== newVal) {
                  model.$setViewValue(newVal);
              }
          }, 500);
      }
    };
});

HTML:

<form name="myForm" ng-submit="login()">
  <label for="username">Username</label>
  <input type="text" id="username" name="username" ng-model="username" auto-fill-sync/><br/>
  <label for="password">Password</label>
  <input type="password" id="password" name="password" ng-model="password" auto-fill-sync/><br/>
  <button type="submit">Login</button>
</form>

समाधान 2 [कोणीय घटनाओं का उपयोग करना]:

Ref: बेको का जवाब

निर्देशक:

app.directive("autofill", function () {
    return {
        require: "ngModel",
        link: function (scope, element, attrs, ngModel) {
            scope.$on("autofill:update", function() {
                ngModel.$setViewValue(element.val());
            });
        }
    };
});

HTML:

<form name="myForm" ng-submit="login()">
  <label for="username">Username</label>
  <input type="text" id="username" name="username" ng-model="username" autofill/><br/>
  <label for="password">Password</label>
  <input type="password" id="password" name="password" ng-model="password" autofill/><br/>
  <button type="submit">Login</button>
</form>

समाधान 3 [रिले विधि कॉल का उपयोग करना]:

निर्देशक:

app.directive('autoFill', function() {
    return {
        restrict: 'A',
        link: function(scope,element) {
            scope.submit = function(){
                scope.username = element.find("#username").val();
                scope.password = element.find("#password").val();
                scope.login();//call a login method in your controller or write the code here itself
            }

        }
    };
});

HTML:

<form name="myForm" auto-fill ng-submit="submit()">
   <label for="username">Username</label>
   <input type="text" id="username" name="username" ng-model="username" />
   <label for="password">Password</label>
   <input type="password" id="password" name="password" ng-model="password" />
   <button type="submit">Login</button>
</form>

2
समाधान 1 ने एक समय के लिए बहुत अच्छा काम किया, लेकिन अब 1.4.9 पर angularjs पर यह काम नहीं करता है। model.$validनिर्देशात्मक रिटर्न की जाँच पहले और बाद दोनों में सही है $setViewValue, लेकिन तत्व अभी भी ng-invalidकक्षा में है
जॉन

4

खैर, यह ब्राउज़र के व्यवहार का अनुकरण करने का सबसे आसान तरीका है, इसलिए यदि परिवर्तन की घटना के साथ कोई समस्या है, तो बस इसे स्वयं आग दें। बहुत सरल।

निर्देशक:

yourModule.directive('triggerChange', function($sniffer) {
    return {
        link : function(scope, elem, attrs) {
            elem.on('click', function(){
                $(attrs.triggerChange).trigger(
                    $sniffer.hasEvent('input') ? 'input' : 'change'
                );
            });
        },
        priority : 1
    }
});

HTML:

<form >
    <input data-ng-model="user.nome" type="text" id="username">

    <input data-ng-model="user.senha" type="password" id="password" >

    <input type="submit" data-ng-click="login.connect()" id="btnlogin" 
           data-trigger-change="#password,#username"/>
</form>

आप कुछ बदलाव कर सकते हैं, जैसे फॉर्म पर डायरेक्शन डालना और फॉर्म सबमिट पर डीडी क्लास के साथ सभी इनपुट्स पर ईवेंट को फायर करना।


3

यह jQuery तरीका है:

$(window).load(function() {
   // updates autofilled fields
   window.setTimeout(function() {
     $('input[ng-model]').trigger('input');
   }, 100);
 });

यह है कोणीय तरीका:

 app.directive('autofill', ['$timeout', function ($timeout) {
    return {
        scope: true,
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {
            $timeout(function(){
                $(elem[0]).trigger('input');
                // elem.trigger('input'); try this if above don't work
            }, 200)
        }
    }
}]);

एचटीएमएल

<input type="number" autofill /> 

2
पूरी तरह से गैर-कोणीय तरीका।
गोरक्षपीठ

1
@gorpacrate: अब इसे कोणीय तरीके से देखें।
निश्चिंत धनानी

2
कोणीय मार्ग के टैब में बहुत अधिक स्थान हैं। मज़ाक। मुझे क्षैतिज स्क्रॉलिंग पसंद है।
डैनियल बायरोव्स्की पोपस्की

यह कोणीय में काम नहीं करता है क्योंकि तत्व पर कोई फ़ंक्शन ट्रिगर नहीं है। मुझे लगता है कि इसके लिए jquery
टॉमस

1
triggerHandler('input')ठीक होना चाहिए अगर आपके पास पूरी तरह से उड़ा हुआ
जेवर

1

यहां एक और वर्कअराउंड है जो कम हैकी है, लेकिन कंट्रोलर में कुछ अतिरिक्त कोड की आवश्यकता होती है।

HTML:

<form ng-submit="submitForm()" ng-controller="FormController">
    <input type="text" ng-model="username" autocomplete-username>
    <input type="submit">
</form>

निर्देश (कॉफीस्क्रिप्ट):

directives.directive 'autocompleteUsername', ->
    return (scope, element) ->
        scope.getUsername = ->
            element.val()

नियंत्रक:

controllers.controller 'FormController', [->
    $scope.submitForm = ->
        username = $scope.getUsername?() ? $scope.username
        # HTTP stuff...
]

आपके पास वेनिला जावास्क्रिप्ट में यह है?
f1lt3r

CoffeeScript.org एक अनुवादक प्रदान करता है: यहाँ किया गया
jab

1

यह एकमात्र समाधान है जो मैंने पाया है कि मेरे सभी कोणीय मान्यताओं को निष्क्रिय करने के लिए काम करने की अनुमति दी गई है जिसमें सबमिट बटन को अक्षम / सक्षम करना शामिल है। बोवर और 1 स्क्रिप्ट टैग के साथ स्थापित करता है। Bazinga!

https://github.com/tbosch/autofill-event


1
यह पॉली फिल फॉर्म राज्य में सबमिट बटन / इनपुट बाइंडिंग के साथ फिट नहीं है। जब तक आप पृष्ठ पर किसी भी बिंदु पर क्लिक करते हैं, जिसे आप डाइजेस्ट को ट्रिगर करना चाहते हैं (ऐसा लगता है कि एक्शन ट्रिगर ब्राउज़र को कुछ वास्तविक भरने के लिए करता है), तो बटन सक्षम हो जाता है। मैनुअल परीक्षण के साथ टेस्ट पेज
ई-क्लाउड

1

मेरे लिए काम किए गए टाइमआउट फ़ंक्शन का उपयोग करने के बजाय मॉडल मान को बदलना।

यहाँ मेरा कोड है:

module.directive('autoFill', [ function() {
    return {
        require: 'ngModel',
        link:function(scope, element, attr, ngModel) {
            var origVal = element.val();
            if(origVal){
                ngModel.$modelValue = ngModel.$modelValue || origVal;
            }
        }
    };
}]);

1

सबमिट हैंडलर में वन-लाइनर वर्कअराउंड (jQuery की आवश्यकता है):

if (!$scope.model) $scope.model = $('#input_field').val();

यह वास्तव में एक-लाइनर नहीं है यदि यह एक निर्देश में है, जो कि निश्चित रूप से होना चाहिए।
इशेरवुड

0

मैं सबमिट पर एक $ setValue (वैल ()) को बाध्य करता हूं: (यह jQuery के बिना काम करता है )

   var ValidSubmit = ['$parse', function ($parse) {
    return {
        compile: function compile(tElement, tAttrs, transclude) {
            return {
                post: function postLink(scope, element, iAttrs, controller) {
                    var form = element.controller('form');
                    form.$submitted = false;
                    var fn = $parse(iAttrs.validSubmit);
                    element.on('submit', function(event) {
                        scope.$apply(function() {
                            var inputs = element.find('input');
                            for(var i=0; i < inputs.length; i++) {
                                var ele = inputs.eq(i);
                                var field = form[inputs[i].name];
                                field.$setViewValue(ele.val());
                            }
                            element.addClass('ng-submitted');
                            form.$submitted = true;
                            if(form.$valid) {
                                fn(scope, {$event:event});
                            }
                        });
                    });
                    scope.$watch(function() { return form.$valid}, function(isValid) {
                        if(form.$submitted == false) return;
                        if(isValid) {
                            element.removeClass('has-error').addClass('has-success');
                        } else {
                            element.removeClass('has-success');
                            element.addClass('has-error');
                        }
                    });
                }
            }
        }
    }
}]
app.directive('validSubmit', ValidSubmit);

0

मैं Angularjs के लिए बहुत नया हूं, लेकिन मुझे उस समस्या का एक सरल समाधान मिला => Angular अभिव्यक्ति की पुनर्मूल्यांकन करने के लिए ... इसे बदलते हुए! (निश्चित रूप से आपको प्रारंभिक अवस्था में वापस लौटने के लिए प्रारंभिक मूल्य को याद रखने की आवश्यकता है) फार्म जमा करने के लिए आपके नियंत्रक फ़ंक्शन में यह तरीका है:

    $scope.submit = function () {
                var oldpassword = $scope.password;
                $scope.password = '';
                $scope.password = oldpassword;
//rest of your code of the submit function goes here...

जहां निश्चित रूप से, आपके पासवर्ड इनपुट में दर्ज किया गया मान खिड़कियों द्वारा निर्धारित किया गया है और उपयोगकर्ता द्वारा नहीं।


0

आप इस कोड को आज़मा सकते हैं:

yourapp.directive('autofill',function () {

    return {
        scope: true,
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {
            var origVal = elem.val();
            if (origVal != '') {
                elem.trigger('input');
            }
        }
    }
});

0

इस उत्तर के लिए एक मामूली संशोधन ( https://stackoverflow.com/a/14966711/3443828 ): $ timeout के बजाय $ अंतराल का उपयोग करें ताकि आपको ब्राउज़र की दौड़ न लगानी पड़े।

mod.directive('autoFillSync', function($interval) {
    function link(scope, element, attrs, ngModel) {
        var origVal = element.val();
        var refresh = $interval(function() {
          if (!ngModel.$pristine) {
            $interval.cancel(refresh);
          }else{
            var newVal = element.val();
            if (origVal !== newVal) {
              ngModel.$setViewValue(newVal);
              $interval.cancel(refresh);
            }
          }
        }, 100);
    }

    return {
      require: 'ngModel',
      link: link
    }
  });

0

यह वह समाधान है जिसे मैंने अपने रूपों में उपयोग करके समाप्त किया है।

.directive('autofillSync', [ function(){
  var link = function(scope, element, attrs, ngFormCtrl){
    element.on('submit', function(event){
      if(ngFormCtrl.$dirty){
        console.log('returning as form is dirty');
        return;
      }   
      element.find('input').each(function(index, input){
        angular.element(input).trigger('input');
      }); 
    }); 
  };  
  return {
    /* negative priority to make this post link function run first */
    priority:-1,
    link: link,
    require: 'form'
  };  
}]);

और फॉर्म का टेम्पलेट होगा

<form autofill-sync name="user.loginForm" class="login-form" novalidate ng-submit="signIn()">
    <!-- Input fields here -->
</form>

इस तरह मैं अपने एनजी-मॉडल पर किसी भी पार्सर / फॉर्मेटर्स को चलाने में सक्षम था और जमा कार्यक्षमता को पारदर्शी था।


0

निर्देशों के बिना समाधान:

.run(["$window", "$rootElement", "$timeout", function($window, $rootElement, $timeout){

        var event =$window.document.createEvent("HTMLEvents");
        event.initEvent("change", true, true);

        $timeout(function(){

            Array.apply(null, $rootElement.find("input")).forEach(function(item){
                if (item.value.length) {
                    item.$$currentValue = item.value;
                    item.dispatchEvent(event);
                }
            });

        }, 500);
    }])

0

यह एक साधारण फिक्स है जो उन सभी मामलों के लिए काम करता है जिन्हें मैंने फ़ायरफ़ॉक्स और क्रोम दोनों में परीक्षण किया है। ध्यान दें कि शीर्ष उत्तर (निर्देश w / टाइमआउट) के साथ मेरे पास मुद्दे थे -

  • ब्राउजर बैक / फॉरवर्ड बटन, पेज लोड इवेंट्स को री-फायर न करें (इसलिए फिक्स लागू नहीं होता)
  • पृष्ठ लोड के कुछ समय बाद क्रेडेंशियल लोड हो रहा है। जैसे फ़ायरफ़ॉक्स में, लॉगिन बॉक्स पर डबल क्लिक करें और संग्रहीत क्रेडेंशियल्स से चयन करें।
  • एक समाधान की आवश्यकता है जो फॉर्म जमा करने से पहले अद्यतन करता है क्योंकि मैं वैध इनपुट प्रदान किए जाने तक लॉगिन बटन को अक्षम करता हूं

यह फिक्स जाहिर तौर पर बहुत गूंगा और हैसी है, लेकिन यह समय के 100% काम करता है -

function myScope($scope, $timeout) {
    // ...
    (function autoFillFix() {
        $timeout(function() { 
            $('#username').trigger('change'); 
            $('#password').trigger('change'); 
            autoFillFix(); }, 500);                    
    })();
}

1
बदल सकते $timeoutके साथ $intervalभविष्य में थोड़ा और अधिक संदर्भ devs और अजीब लग रही पुनरावर्ती कॉल वहाँ पर जा रहा से छुटकारा देने के लिए
Mutmatt

0

इनमें से किसी भी समाधान ने मेरे उपयोग के मामले में काम नहीं किया। मेरे पास कुछ फॉर्म फ़ील्ड हैं जो परिवर्तन के लिए देखने के लिए एनजी-परिवर्तन का उपयोग करते हैं। का उपयोग करते हुए$watch कोई मदद नहीं है क्योंकि यह ऑटोफिल द्वारा ट्रिगर नहीं किया गया है। चूंकि मेरे पास कोई सबमिट बटन नहीं है, इसलिए कुछ समाधानों को चलाने का कोई आसान तरीका नहीं है और मैं अंतराल का उपयोग करने में सफल नहीं था।

मैंने ऑटोफ़िल को अक्षम करना समाप्त कर दिया - आदर्श नहीं, लेकिन उपयोगकर्ता के लिए बहुत कम भ्रमित।

<input readonly onfocus="this.removeAttribute('readonly');">

यहां जवाब मिला


-1

यदि आप jQuery का उपयोग कर रहे हैं तो आप फॉर्म सबमिट पर ऐसा कर सकते हैं:

HTML:

<form ng-submit="submit()">
    <input id="email" ng-model="password" required 
           type="text" placeholder="Your email">
    <input id="password" ng-model="password" required 
           type="password" placeholder="Password">
</form>

जे एस:

 $scope.submit = function() {
     $scope.password = $('#password').val();
}

1
हालांकि यह काम कर सकता है यह अधिक जटिल रूपों के लिए उचित नहीं है।
Origin1tech

-1

यदि आप इसे सरल रखना चाहते हैं तो केवल जावास्क्रिप्ट का उपयोग करके मूल्य प्राप्त करें

अपने कोणीय js नियंत्रक में:

var उपयोगकर्ता नाम = document.getElementById ('उपयोगकर्ता नाम') मान;


मुझे लगता है कि आप नहीं समझते कि समस्या क्या है
aelor
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.