Cum să utilizați „ng-model” în AngularJS cu EXEMPLE

⚡ Rezumat inteligent

ng-model în AngularJS leagă un control de intrare direct de o proprietate pe $scope, keeping vizualizarea și modelul sincronizate în ambele direcții. Secțiunile de mai jos acoperă atributul, trei exemple practice și erorile pe care începătorii le întâmpină cel mai des.

  • 🔗 Legare bidirecțională: ng-model introduce automat datele introduse de utilizator în proprietatea $scope și introduce automat modificările controlerului înapoi în control.
  • 📝 Legarea zonei de text: Leagă un șir de caractere cu mai multe linii la o zonă de text și folosește secvența de escape \n pentru a forța întreruperi de linie în valoarea redată.
  • ☑️ Stare casetă de selectare: O casetă de selectare legată de ng-model stochează o valoare booleană, deci true afișează caseta ca bifată, iar false o lasă goală.
  • 📋 Liste derulante: Populează un element select cu ng-options și leagă elementul ales la o proprietate separată a modelului.
  • ⚠️ Eșec comun: Legarea unei selecții la același obiect care furnizează textul opțiunii sale suprascrie acel obiect la prima selecție.
  • 🛠️ Cârlige de validare: ng-model adaugă clase ng-pristine, ng-dirty, ng-valid și ng-invalid care conduc stilul condiționat și verificările de formulare.

Ce este ng-model în AngularJS?

ng-model este o directivă în AngularJS care reprezintă modelul, iar scopul său principal este de a lega „view”-ul de „model”. Orice introduce utilizatorul într-un control este scris direct într-o proprietate pe $scopeși orice scrie controlerul la acea proprietate este împins direct înapoi în control.

De exemplu, să presupunem că doriți să prezentați utilizatorului final o pagină simplă, precum cea de mai jos, care îi cere acestuia să introducă „Prenumele” și „Numele” în casete de text. Apoi, doriți să vă asigurați că stocați informațiile introduse de utilizator în modelul de date.

Puteți utiliza directiva ng-model pentru a mapa câmpurile text „Prenume” și „Nume” la modelul dvs. de date. Directiva va asigura că datele din „vizualizare” și cele din „model” sunt sincronizate în permanență, fără nicio linie de cod de gestionare a evenimentelor.

⚠️ Notă privind versiunea: AngularJS (ramura 1.x) a ajuns la sfârșitul perioadei de funcționare pe 31 decembrie 2021 și nu mai primește patch-uri de securitate. Exemplele de mai jos rulează în continuare, dar în Angular modern aceeași legătură bidirecțională este scrisă ca [(ngModel)] și necesită FormsModule.

Atributul ng-model

Așa cum s-a discutat în secțiunea de mai sus, atributul ng-model este utilizat pentru a lega datele din model la vizualizarea prezentată utilizatorului.

Atributul ng-model este folosit pentru,

  1. Legarea controalelor precum introducerea datelor, zona de text și selectarea elementelor din vizualizare în model.
  2. Furnizarea unui comportament de validare — de exemplu, o validare poate fi adăugată la o casetă text, astfel încât să poată fi introduse doar caractere numerice.
  3. Menținerea stării controlului. Prin stare, înțelegem că controlul și datele sunt întotdeauna sincronizate: dacă valoarea datelor se modifică, valoarea din control se modifică automat și invers.
  4. Expunerea acelei stări ca clase CSS. AngularJS adaugă ng-pristine, ng-dirty, ng-valid și ng-invalid pentru fiecare control care poartă un model ng, ceea ce simplifică stilizarea condiționată a formularelor.

Odată ce atributul este înțeles, următorul pas este să îl aplici celor trei tipuri de control pe care le vei întâlni cel mai des.

Cum se utilizează ng-model

1) Zona de text

Eticheta zonă de text este utilizată pentru a defini un control de introducere a textului pe mai multe linii. Zona de text poate conține un număr nelimitat de caractere, iar textul este redat într-un font cu lățime fixă.

Așadar, haideți să vedem un exemplu simplu despre cum putem adăuga directiva ng-model la un control din zona de text. În acest exemplu, vrem să arătăm cum putem transmite un șir multilinie de la controler la vizualizare și să atașăm acea valoare la controlul din zona de text.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
    <script src="https://code.angularjs.org/1.8.3/angular.js"></script>
</head>
<body>
<h1>Guru99 Global Event</h1>

<div ng-app="DemoApp" ng-controller="DemoCtrl">
    <form>
        Topic Description:<br><br>
        <textarea rows="4" cols="50" ng-model="pDescription"></textarea>
    </form>
</div>

<script>
    var app = angular.module('DemoApp', []);
    app.controller('DemoCtrl', function($scope) {
        $scope.pDescription = "This topic looks at how Angular JS works \nModels in Angular JS";
    });
</script>
</body>
</html>

Code Explicaţie:

  1. directiva ng-model atașează variabila membru numită „pDescript„ion” la controlul „textarea”. Funcția „pDescriptVariabila „ion” conține textul care este transmis controlului zonei de text. rows="4" și cols="50" Atributele pur și simplu dimensionează controlul astfel încât textul pe mai multe rânduri să fie afișat corect.
  2. Variabila membru „pDescript„ion” i se atribuie o valoare pe mai multe linii. \n Secvența de escape din interiorul șirului este cea care forțează textul pe o a doua linie atunci când zona de text îl afișează.

ieșire:

Din rezultat, este clar că textul multilinial atribuit în controler este afișat în controlul zonei de text, împărțit pe două linii exact acolo unde \n sta.

2) Elemente de intrare

Directiva ng-model funcționează și cu elemente de intrare obișnuite. Mai jos legăm o casetă de text și două casete de selectare simultan, astfel încât să puteți vedea cum ng-model gestionează o valoare de tip șir de caractere și o valoare booleană una lângă alta.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
    <script src="https://code.angularjs.org/1.8.3/angular.js"></script>
</head>
<body>
<h1>Guru99 Global Event</h1>

<div ng-app="DemoApp" ng-controller="DemoCtrl">
    <form>
        Topic Description:<br><br>
        Name : <input type="text" ng-model="pname"><br>
        Topic :<br>
        <input type="checkbox" ng-model="Topic.Controller">Controller<br>
        <input type="checkbox" ng-model="Topic.Models">Models
    </form>
</div>

<script>
    var app = angular.module('DemoApp', []);
    app.controller('DemoCtrl', function($scope) {
        $scope.pname = "Guru99";

        $scope.Topic = {
            Controller: true,
            Models: false
        };
    });
</script>
</body>
</html>

Code Explicaţie:

  1. Directiva ng-model atașează variabila membru „pname” la controlul de introducere a textului, iar proprietățile Topic.Controller și Topic.Models la cele două controale ale casetei de selectare.
  2. În controler, „pname” primește șirul de caractere „Guru99”, iar obiectului „Topic” i se atribuie doi membri booleeni. O casetă de selectare legată de ng-model citește și scrie întotdeauna o valoare booleană, motiv pentru care true afișează caseta ca fiind bifată și false o lasă clară.

ieșire:

Din ieșire,

  • Se poate observa clar că valoarea atribuită pname variabila este „Guru99. "
  • Deoarece prima valoare legată este true, caseta de selectare este marcată pentru caseta de selectare „Controller”. De asemenea, deoarece a doua valoare este false, caseta de selectare nu este marcată pentru caseta de selectare „Modele”.

3) Selectați elementul din meniul drop-down

Directiva ng-model poate fi aplicată și elementului select, astfel încât elementul ales de utilizator să fie stocat în model.

Aici vom avea o introducere de text care conține numele „Guru99” și o listă de selecție cu două elemente de listă, „Controller” și „Modele”.

⚠️ Corecție: Captura de ecran de mai sus arată listarea originală, care lega elementul select la același Topics obiectul care a furnizat textul opțiunii. În momentul în care un utilizator alege o opțiune, AngularJS suprascrie Topics cu șirul selectat și ambele opțiuni dispar. Listarea corectată de mai jos păstrează lista într-o proprietate și selecția în alta și folosește ng-options pentru a construi lista.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
    <script src="https://code.angularjs.org/1.8.3/angular.js"></script>
</head>
<body>
<h1>Guru99 Global Event</h1>

<div ng-app="DemoApp" ng-controller="DemoCtrl">
    <form>
        Topic Description:<br><br>
        Name : <input type="text" ng-model="pName"><br>
        Topic :<br>
        <!-- Topics holds the list; selectedTopic holds the choice -->
        <select ng-model="selectedTopic" ng-options="t for t in Topics"></select>
    </form>
</div>

<script>
    var app = angular.module('DemoApp', []);
    app.controller('DemoCtrl', function($scope) {
        $scope.pName = "Guru99";

        $scope.Topics = ["Controller", "Models"];
        $scope.selectedTopic = $scope.Topics[0];
    });
</script>
</body>
</html>

Code Explicaţie:

  1. Introducerea de text este legată de pName, iar elementul select este legat de selectedTopicDeoarece select are propria proprietate de model, alegerea unei opțiuni nu perturbă niciodată lista în sine.
  2. Topics matricea conține cele două valori „Controller” și „Models”. ng-options expresia parcurge acel array și afișează o opțiune per intrare, așadar adăugarea unui al treilea subiect nu necesită nicio modificare a markup-ului.
  3. selectedTopic este prestabilit la prima intrare, ceea ce face ca meniul derulant să se deschidă cu o valoare implicită rezonabilă în loc de un rând gol.

ieșire:

Din rezultat, se poate observa că valoarea atribuită pName variabila este „Guru99”, iar controlul select oferă opțiunile „Controller” și „Models”. Pe lângă exemplele funcționale, legăturile refuză uneori să se actualizeze, iar motivele merită cunoscute.

De ce legăturile ng-model eșuează uneori

Majoritatea problemelor raportate cu ng-model nu sunt erori în AngularJS, ci consecințe ale modului în care funcționează scopurile și primitivele.

Cazul clasic este o legătură plasată în interiorul unei directive care creează un domeniu copil, cum ar fi ng-repetă, ng-if sau ng-switch. Scriere ng-model="name" creează o copie umbră pe domeniul de aplicare copil, astfel încât părintele nu vede niciodată editarea. Legarea la o proprietate a unui obiect în schimb — ng-model="user.name" — menține fiecare domeniu de aplicare îndreptat către aceeași referință. Acesta este motivul pentru care dezvoltatorii AngularJS experimentați insistă asupra unui punct în fiecare expresie ng-model.

Două alte cauze explică majoritatea celorlalte:

  • Controler sau modul lipsă: Dacă ng-app sau ng-controller sunt scrise greșit, legătura nu redă nimic în mod silențios, ci doar generează o eroare.
  • Valoare modificată în afara AngularJS: o valoare setată dintr-un handler jQuery sau o apelare setTimeout ajunge în afara ciclului de digest, deci vizualizarea nu se reîmprospătează până când $scope.$apply() se execută.

Verificarea acestor trei lucruri rezolvă marea majoritate a legăturilor care par să nu funcționeze.

Întrebări frecvente

ng-bind este unidirecțional: imprimă o valoare a modelului într-un element. ng-model este bidirecțional și funcționează doar pe controalele de formular, astfel încât datele introduse de utilizator sunt trimise înapoi în model, precum și în afara acestuia.

Adăugați ng-model-options, de exemplu ng-model-options=”{ debounce: 500 }”. AngularJS așteaptă apoi o jumătate de secundă după ultima apăsare de tastă înainte de a actualiza modelul, ceea ce este util pentru casetele de căutare care declanșează o cerere.

În mare parte, da. Asistenții AI rescriu ng-model ca [(ngModel)] și adaugă importul FormsModule. Formularele reactive, parserele personalizate și conductele $formatters necesită în continuare revizuire manuală, deoarece Angular le modelează foarte diferit.

Instrumentele de inteligență artificială verifică rapid suspecții obișnuiți: o limită primitivă în interiorul unui domeniu de aplicare copil, un nume de controler scris greșit și o valoare atribuită în afara ciclului de digest. Fiecare dintre acestea produce o eroare silențioasă, mai degrabă decât o eroare de consolă.

Doar intrarea type=”number” este analizată ca o valoare numerică. Un control type=”text” generează întotdeauna un șir de caractere, deci comparațiile cu === eșuează. Convertiți explicit sau schimbați tipul de intrare.

Rezumați această postare cu: