[angularjs] एक इनपुट में एनजी मॉडल पर फ़िल्टर



Answers

मेरा मानना ​​है कि AngularJS इनपुट और ngModel direcive का इरादा यह है कि अवैध इनपुट मॉडल में कभी खत्म नहीं होना चाहिए । मॉडल हमेशा वैध होना चाहिए। अमान्य मॉडल होने में समस्या यह है कि हमारे पास ऐसे दर्शक हो सकते हैं जो अमान्य मॉडल के आधार पर आग लगते हैं और (अनुचित) कार्य करते हैं।

जैसा कि मैंने इसे देखा है, यहां उचित समाधान $parsers पाइपलाइन में प्लग करना है और यह सुनिश्चित करना है कि अमान्य इनपुट मॉडल में नहीं बना है। मुझे यकीन नहीं है कि आपने चीजों से संपर्क करने की कोशिश की है या आपने $parsers साथ वास्तव में क्या काम नहीं किया है, लेकिन यहां एक सरल निर्देश है जो आपकी समस्या को हल करता है (या कम से कम समस्या की मेरी समझ):

app.directive('customValidation', function(){
   return {
     require: 'ngModel',
     link: function(scope, element, attrs, modelCtrl) {

       modelCtrl.$parsers.push(function (inputValue) {

         var transformedInput = inputValue.toLowerCase().replace(/ /g, ''); 

         if (transformedInput!=inputValue) {
           modelCtrl.$setViewValue(transformedInput);
           modelCtrl.$render();
         }         

         return transformedInput;         
       });
     }
   };
});

जैसे ही उपर्युक्त निर्देश घोषित किया जाता है, इसका उपयोग इस प्रकार किया जा सकता है:

<input ng-model="sth" ng-trim="false" custom-validation>

जैसा कि @ वैलेंन्टिन श्याबानोव द्वारा प्रस्तावित समाधान में हमें ng-trim निर्देश ng-trim उपयोग करने की आवश्यकता है यदि हम इनपुट की शुरुआत / अंत में रिक्त स्थान को अस्वीकार करना चाहते हैं।

इस दृष्टिकोण का लाभ 2 गुना है:

  • अवैध मान मॉडल के लिए प्रचारित नहीं है
  • निर्देश का उपयोग करना, इस कस्टम सत्यापन को किसी भी इनपुट में बार-बार वॉचर्स को डुप्लिकेट किए बिना जोड़ना आसान है
Question

मेरे पास एक टेक्स्ट इनपुट है और मैं उपयोगकर्ताओं को रिक्त स्थान का उपयोग करने की अनुमति नहीं देना चाहता, और टाइप की गई सभी चीज़ों को लोअरकेस में बदल दिया जाएगा।

मुझे पता है कि मुझे एनजी-मॉडल उदाहरण पर फिल्टर का उपयोग करने की अनुमति नहीं है।

ng-model='tags | lowercase | no_spaces'

मैंने अपना खुद का निर्देश बनाने पर ध्यान दिया लेकिन $parsers और $parsers फ़ंक्शंस जोड़ने से इनपुट अपडेट नहीं हुआ, केवल अन्य तत्व जिनके पास ng-model था।

मैं उस इनपुट को कैसे बदल सकता हूं जिसमें मैं वर्तमान में टाइप कर रहा हूं?

मैं अनिवार्य रूप से 'टैग' सुविधा बनाने की कोशिश कर रहा हूं जो स्टैक ओवरफ्लो पर यहां की तरह काम करता है।




मुझे एक जैसी समस्या थी और इस्तेमाल किया गया था

ng-change="handler(objectInScope)" 

मेरे हैंडलर में मैं ऑब्जेक्ट इनस्कोप की विधि को सही तरीके से संशोधित करने के लिए कॉल करता हूं (मोटे इनपुट)। नियंत्रक में मैंने कहीं कहीं शुरू किया है

$scope.objectInScope = myObject; 

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




यदि आप जटिल, एसिंक इनपुट सत्यापन कर रहे हैं, तो यह अपने स्वयं के सत्यापन विधियों के साथ कस्टम क्लास के हिस्से के रूप में एक स्तर को अमूर्त ng-model लिए लायक हो सकता है।

https://plnkr.co/edit/gUnUjs0qHQwkq2vPZlpO?p=preview

एचटीएमएल

<div>

  <label for="a">input a</label>
  <input 
    ng-class="{'is-valid': vm.store.a.isValid == true, 'is-invalid': vm.store.a.isValid == false}"
    ng-keyup="vm.store.a.validate(['isEmpty'])"
    ng-model="vm.store.a.model"
    placeholder="{{vm.store.a.isValid === false ? vm.store.a.warning : ''}}"
    id="a" />

  <label for="b">input b</label>
  <input 
    ng-class="{'is-valid': vm.store.b.isValid == true, 'is-invalid': vm.store.b.isValid == false}"
    ng-keyup="vm.store.b.validate(['isEmpty'])"
    ng-model="vm.store.b.model"
    placeholder="{{vm.store.b.isValid === false ? vm.store.b.warning : ''}}"
    id="b" />

</div>

कोड

(function() {

  const _ = window._;

  angular
    .module('app', [])
    .directive('componentLayout', layout)
    .controller('Layout', ['Validator', Layout])
    .factory('Validator', function() { return Validator; });

  /** Layout controller */

  function Layout(Validator) {
    this.store = {
      a: new Validator({title: 'input a'}),
      b: new Validator({title: 'input b'})
    };
  }

  /** layout directive */

  function layout() {
    return {
      restrict: 'EA',
      templateUrl: 'layout.html',
      controller: 'Layout',
      controllerAs: 'vm',
      bindToController: true
    };
  }

  /** Validator factory */  

  function Validator(config) {
    this.model = null;
    this.isValid = null;
    this.title = config.title;
  }

  Validator.prototype.isEmpty = function(checkName) {
    return new Promise((resolve, reject) => {
      if (/^\s+$/.test(this.model) || this.model.length === 0) {
        this.isValid = false;
        this.warning = `${this.title} cannot be empty`;
        reject(_.merge(this, {test: checkName}));
      }
      else {
        this.isValid = true;
        resolve(_.merge(this, {test: checkName}));
      }
    });
  };

  /**
   * @memberof Validator
   * @param {array} checks - array of strings, must match defined Validator class methods
   */

  Validator.prototype.validate = function(checks) {
    Promise
      .all(checks.map(check => this[check](check)))
      .then(res => { console.log('pass', res)  })
      .catch(e => { console.log('fail', e) })
  };

})();



यदि आप केवल इनपुट फ़ील्ड को पढ़ रहे हैं, तो आप फिल्टर के साथ एनजी-वैल्यू का उपयोग कर सकते हैं।

उदाहरण के लिए:

ng-value="price | number:8"



Related