WebHU - Programozási kérdések és válaszok

szűrők ng-modell egy bemenetben

Szövegbevitelem van, és nem szeretném megengedni a felhasználóknak, hogy szóközt használjanak, és minden beírt kisbetűre lesz írva.

Tudom, hogy nem használhatok szűrőket az ng-modellben, pl.

ng-model='tags | lowercase | no_spaces'

Megnéztem a saját direktívám létrehozását, de a $parsers és $formatters függvények hozzáadása nem frissítette a bemenetet, csak más elemeket, amelyeken ng-model volt.

Hogyan változtathatom meg az éppen beírt bevitelt?

Lényegében megpróbálom létrehozni a "címkék" funkciót, amely ugyanúgy működik, mint itt a StackOverflow-n.



Válaszok:


1

Azt javaslom, hogy nézze meg a modell értékét, és frissítse a változás után: http://plnkr.co/edit/Mb0uRyIIv1eK8nTg3Qng?p=preview

Az egyetlen érdekes probléma a szóközökkel van: Az AngularJS 1.0.3-ban az ng-model a bemeneten automatikusan levágja a karakterláncot, így nem észleli, hogy a modell megváltozott, ha szóközt ad hozzá a végén vagy az elején (így a szóközöket nem távolítja el automatikusan kód). Az 1.1.1-es verzióban azonban van egy „ng-trim” direktíva, amely lehetővé teszi ennek a funkciónak a letiltását (commit) . Ezért úgy döntöttem, hogy az 1.1.1-et használom a kérdésében leírt pontos funkcionalitás eléréséhez.

19.01.2013
  • Pontosan ezt kerestem. Kiderült, hogy már az angularjs 1.1.1-et használom 20.01.2013
  • @Valentyn, a megoldásod a fenti megjegyzésben hivatkozott SO kérdésre vonatkozott. Kösz. stackoverflow.com/questions/12176925/ 20.01.2013
  • ennek a megoldásnak lehetnek rossz mellékhatásai, lásd alább a másik választ, erre direktívát kell használni 01.10.2014
  • Ha a hatókörváltozót a $watch-en belülről újra hozzárendeli, akkor a figyelőt ismét meg kell hívni. Egyszerű esetekben (ahol a szűrő idempotens) a szűrő minden módosításnál kétszer fut le. 05.12.2014

  • 2

    Úgy gondolom, hogy az AngularJS bemenetek és a ngModel irányelv célja az, hogy az érvénytelen bemenet soha ne kerüljön a modellbe. A modellnek mindig érvényesnek kell lennie. Az érvénytelen modellel az a probléma, hogy lehetnek megfigyelőink, akik az érvénytelen modell alapján tüzelnek és (nem megfelelő) műveleteket hajtanak végre.

    Ahogy én látom, a megfelelő megoldás itt az, ha csatlakoztatjuk a $parsers csővezetéket, és megbizonyosodunk arról, hogy az érvénytelen bemenet ne kerüljön be a modellbe. Nem tudom, hogyan próbáltad megközelíteni a dolgokat, vagy pontosan mi az, ami nem működött neked a $parsers használatával, de itt van egy egyszerű direktíva, amely megoldja a problémádat (vagy legalábbis a probléma megértését):

    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;         
           });
         }
       };
    });
    

    Amint a fenti direktíva deklarálva van, a következőképpen használható:

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

    A @Valentyn Shybanov által javasolt megoldáshoz hasonlóan a ng-trim direktívát kell használnunk, ha meg akarjuk tiltani a szóközöket a bemenet elején/végén.

    Ennek a megközelítésnek az előnye kettős:

    • Érvénytelen érték nem kerül a modellbe
    • Egy direktíva használatával könnyen hozzáadható ez az egyéni érvényesítés bármely bemenethez anélkül, hogy a megfigyelőket újra és újra megkettőzné
    20.01.2013
  • Biztos vagyok benne, hogy ez a trükkös rész modelCtrl.$setViewValue(transformedInput); modelCtrl.$render(); Hasznos lenne a dokumentációhoz vezető link: docs. angularjs.org/api/ng.directive:ngModel.NgModelController A megoldásom védelmére egy szó az, hogy a hatókör tulajdonságát nem csak a nézetek alapján lehet megváltoztatni, és az én módszerem is ezt fedi. Tehát úgy gondolom, hogy a tényleges helyzettől függ, hogyan módosítható a hatály. 26.01.2013
  • mire utal a 'modelCtrl' a példádban? 17.05.2013
  • Honnan veszi az inputValue értéket? 23.05.2013
  • Ez tényleg fantasztikus! Nekem bevált. Kösz 19.10.2013
  • A legjobb megoldás valaha! 12.03.2014
  • @GSto modelCtrl az irányelv által megkövetelt vezérlő. (require 'ngModel') 10.04.2014
  • @Dofs A bemeneti érték a modellérték megváltozásakor kerül átadásra – lásd: github.com/angular/angular.js/blob/master/src/ng/directive/ 10.04.2014
  • Szép! Ez legyen az elfogadott válasz – az érvénytelen adatokat a modellen kívül hagyni sokkal jobb, mint a változásokat figyelni és visszamenőlegesen frissíteni. Remek válasz. 12.08.2014
  • A kurzor a szövegmező végére ugrik minden alkalommal, amikor érvénytelen karaktert ír be, próbálja meg beírni a "világ" szót, és módosítsa a "Hello world"-re! 17.01.2015
  • Elnézést kérünk, hogy 2+ éves választ adunk, de beállíthatja az attrs.ngTrim = 'false' értéket is a link() függvényben, így elkerülheti az attribútum hozzáadását az elemhez. Úgy tűnik, hogy karakterláncnak kell lennie, nem logikai értéknek. 02.06.2015
  • A beépített ngList direktíva pontosan ezt teszi 22.12.2017
  • Köszönöm. Lehetséges hasonlót, a modell módosítása nélkül? Úgy értem, szeretném a szűrőt használni a bemeneti szám pénznemként való megjelenítésére anélkül, hogy a modellt karakterláncra módosítanám 06.04.2018

  • 3

    A probléma megoldása a vezérlőoldali szűrők alkalmazása lehet:

    $scope.tags = $filter('lowercase')($scope.tags);

    Ne felejtse el deklarálni a $filter-t függőségként.

    14.01.2014
  • De kell rajta egy $watch, ha azt akarod, hogy megfelelően frissüljön. 09.06.2014
  • ezt csak egyszer hajtják végre. és az órához való hozzáadás nem a megfelelő megoldás, mert ez még kezdetben is lehetővé teszi a modell érvénytelenné válását – a helyes megoldás az, ha hozzáadjuk a modell $elemzőihez. 26.02.2016
  • Nem kell, hogy tetsszen a válaszom, de ez nem jelenti azt, hogy rossz. Ellenőrizd az egódat, mielőtt negatívan szavazol. 28.02.2016

  • 4

    Ha csak olvasható beviteli mezőt használ, használhatja az ng-értéket szűrővel.

    például:

    ng-value="price | number:8"
    
    10.12.2017
  • +1 Ez nem biztos, hogy pontosan a feltett kérdésre válaszol, de hasznos lehet mások számára, akiknek a helyzete kissé eltérő lehet. 22.12.2020

  • 5

    Használjon olyan direktívát, amely hozzáadja a $formaters és $parsers gyűjteményt is, hogy biztosítsa az átalakítás mindkét irányban történő végrehajtását.

    Tekintse meg ezt a másik választ további részletekért, beleértve a jsfiddle linket.

    20.10.2015

    6

    Nekem is volt hasonló problémám és használtam

    ng-change="handler(objectInScope)" 
    

    a kezelőmben meghívom az objectInScope metódusát, hogy helyesen módosítsa magát (durva bemenet). A vezérlőben valahol ezt kezdeményeztem

    $scope.objectInScope = myObject; 
    

    Tudom, hogy ez nem használ semmiféle divatos szűrőt vagy figyelőt... de egyszerű és nagyszerűen működik. Ennek egyetlen hátránya, hogy az objectInScope a hívásban elküldésre kerül a kezelőnek...

    07.10.2014

    7

    Ha összetett, aszinkron bemeneti ellenőrzést végez, érdemes lehet ng-model egy szinttel feljebb absztrahálni egy egyéni osztály részeként, saját érvényesítési módszerekkel.

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

    html

    <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>
    

    kód

    (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) })
      };
    
    })();
    
    02.05.2016

    8

    Ezt kipróbálhatod

    $scope.$watch('tags ',function(){
    
        $scope.tags = $filter('lowercase')($scope.tags);
    
    });
    
    19.01.2016
    Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..