Come utilizzare "ng-model" in AngularJS con ESEMPI

โšก Riepilogo intelligente

ng-model in AngularJS collega un controllo di input direttamente a una proprietร  su $scope, mantieniping La vista e il modello sono sincronizzati in entrambe le direzioni. Le sezioni seguenti illustrano l'attributo, tre esempi pratici e gli errori piรน comuni commessi dai principianti.

  • ๐Ÿ”— Rilegatura a due vie: ng-model inserisce l'input dell'utente nella proprietร  $scope e invia automaticamente le modifiche del controller al controllo stesso.
  • ๐Ÿ“ Collegamento della textarea: Associa una stringa multilinea a una textarea e utilizza la sequenza di escape \n per forzare le interruzioni di riga nel valore visualizzato.
  • โ˜‘๏ธ Stato della casella di controllo: Una casella di controllo associata a ng-model memorizza un valore booleano: se impostato su true, la casella risulta selezionata, mentre se impostato su false la lascia deselezionata.
  • ๐Ÿ“‹ Elenchi a discesa: Popola un elemento select con ng-options e associa l'elemento selezionato a una proprietร  del modello separata.
  • โš ๏ธ Errore comune: Associare un elemento select allo stesso oggetto che fornisce il testo delle opzioni sovrascrive tale oggetto alla prima selezione.
  • ๏ธ Hook di validazione: ng-model aggiunge le classi ng-pristine, ng-dirty, ng-valid e ng-invalid che guidano lo stile condizionale e i controlli dei moduli.

Cos'รจ il modello ng in AngularJS?

ng-model รจ una direttiva in AngularJS che rappresenta il modello e il suo scopo principale รจ quello di collegare la "vista" al "modello". Qualunque cosa l'utente digiti in un controllo viene scritta direttamente in una proprietร  su $scopee qualsiasi cosa il controller scriva in quella proprietร  viene immediatamente rimandata al controllo.

Ad esempio, supponiamo di voler presentare all'utente finale una semplice pagina come quella mostrata di seguito, che chiede all'utente di inserire "Nome" e "Cognome" in appositi campi di testo. Successivamente, vorremmo assicurarci di memorizzare le informazioni inserite dall'utente nel nostro modello dati.

รˆ possibile utilizzare la direttiva ng-model per mappare i campi di testo "Nome" e "Cognome" al modello dati. La direttiva garantirร  che i dati nella "vista" e quelli del "modello" rimangano sempre sincronizzati, senza bisogno di scrivere una sola riga di codice per la gestione degli eventi.

โš ๏ธ Nota sulla versione: AngularJS (il ramo 1.x) ha raggiunto la fine del suo ciclo di vita il 31 dicembre 2021 e non riceve piรน patch di sicurezza. Gli esempi seguenti funzionano ancora, ma nell'Angular moderno lo stesso binding bidirezionale รจ scritto come [(ngModel)] e richiede il modulo FormsModule.

L'attributo del modello ng

Come discusso nella sezione precedente, l'attributo ng-model viene utilizzato per collegare i dati del modello alla vista presentata all'utente.

L'attributo ng-model viene utilizzato per,

  1. Collegamento di controlli quali input, area di testo ed elementi di selezione nella vista al modello.
  2. Implementare un comportamento di validazione: ad esempio, รจ possibile aggiungere una validazione a una casella di testo in modo che siano ammessi solo caratteri numerici.
  3. Mantenimento dello stato del controllo. Per stato si intende che il controllo e i dati sono sempre mantenuti sincronizzati: se il valore dei dati cambia, il valore nel controllo cambia automaticamente e viceversa.
  4. Esporre quello stato come classi CSS. AngularJS aggiunge ng-pristine, ng-dirty, ng-valid and ng-invalid ad ogni controllo che trasporta un ng-model, ed รจ questo che semplifica la stilizzazione condizionale dei moduli.

Una volta compreso l'attributo, il passo successivo รจ applicarlo ai tre tipi di controllo che incontrerete piรน frequentemente.

Come utilizzare il modello ng

1) Area di testo

Il tag dell'area di testo viene utilizzato per definire un controllo di input di testo su piรน righe. L'area di testo puรฒ contenere un numero illimitato di caratteri e il testo viene visualizzato con un carattere a larghezza fissa.

Vediamo ora un semplice esempio di come aggiungere la direttiva ng-model a un controllo area di testo. In questo esempio, mostreremo come passare una stringa multilinea dal controller alla vista e associare tale valore al controllo area di testo.

<!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 Spiegazione:

  1. Migliori direttiva sul modello ng allega la variabile membro chiamata โ€œpDescriptioneโ€ al controllo โ€œtextareaโ€. Il โ€œpDescriptLa variabile "ion" contiene il testo che viene passato al controllo dell'area di testo. rows="4" and cols="50" Gli attributi si limitano a dimensionare il controllo in modo che il testo su piรน righe venga visualizzato correttamente.
  2. La variabile membro โ€œpDescriptallo ioneโ€ viene assegnato un valore multilinea. \n La sequenza di escape all'interno della stringa รจ ciรฒ che forza il testo su una seconda riga quando la textarea lo visualizza.

Produzione:

Dall'output, รจ chiaro che il testo multilinea assegnato nel controller viene visualizzato nel controllo dell'area di testo, diviso su due righe esattamente dove \n si siede.

2) Elementi di input

La direttiva ng-model funziona anche con i normali elementi di input. Di seguito, colleghiamo contemporaneamente una casella di testo e due caselle di controllo, in modo da poter vedere come ng-model gestisce un valore stringa e un valore booleano affiancati.

<!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 Spiegazione:

  1. La direttiva ng-model collega la variabile membro โ€œpnameโ€ al controllo di input di testo e le proprietร  Topic.Controller and Topic.Models ai due controlli a casella di controllo.
  2. Nel controller, a โ€œpnameโ€ viene assegnata la stringa โ€œGuru99โ€, e allโ€™oggetto โ€œTopicโ€ vengono assegnati due membri booleani. Una casella di controllo associata a ng-model legge e scrive sempre un booleano, motivo per cui true rende la casella selezionata e false lo lascia chiaro.

Produzione:

Dall'uscita,

  • Si puรฒ vedere chiaramente che il valore assegnato al pname la variabile รจ โ€œGuru99 ".
  • Poichรฉ il primo valore limite รจ true, la casella di controllo รจ contrassegnata per la casella di controllo โ€œControllerโ€. Allo stesso modo, poichรฉ il secondo valore รจ falseLa casella di controllo "Modelli" non รจ selezionata.

3) Seleziona l'elemento dal menu a discesa

La direttiva ng-model puรฒ essere applicata anche all'elemento select, in modo che l'elemento scelto dall'utente venga memorizzato nel modello.

Qui avremo un campo di testo che contiene il nome "Guru99โ€, e un elenco a discesa con due elementi, โ€œControllerโ€ e โ€œModelliโ€.

โš ๏ธ Correzione: Lo screenshot qui sopra mostra l'elenco originale, che associava l'elemento select allo stesso Topics oggetto che ha fornito il testo dell'opzione. Nel momento in cui un utente sceglie un'opzione, AngularJS sovrascrive Topics con la stringa selezionata ed entrambe le opzioni scompaiono. L'elenco corretto qui sotto mantiene l'elenco in una proprietร  e la selezione in un'altra e utilizza ng-options per creare la 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 Spiegazione:

  1. L'input di testo รจ associato a pNamee l'elemento select รจ associato a selectedTopicPoichรฉ l'elemento select ha una propria proprietร  modello, la scelta di un'opzione non modifica mai l'elenco stesso.
  2. Migliori Topics L'array contiene i due valori "Controller" e "Models". ng-options L'espressione attraversa l'array e visualizza un'opzione per ogni voce, quindi l'aggiunta di un terzo argomento non richiede alcuna modifica al markup.
  3. selectedTopic รจ preimpostato sulla prima voce, ed รจ questo che fa sรฌ che il menu a tendina si apra con un valore predefinito sensato invece che con una riga vuota.

Produzione:

Dall'output si puรฒ vedere che il valore assegnato al pName la variabile รจ โ€œGuru99โ€, e il controllo di selezione offre le opzioni โ€œControllerโ€ e โ€œModelliโ€. A parte gli esempi funzionanti, a volte i binding si rifiutano di aggiornarsi, ed รจ utile conoscerne i motivi.

Perchรฉ a volte i binding ng-model falliscono

La maggior parte dei problemi segnalati relativi a ng-model non sono bug di AngularJS, ma conseguenze del funzionamento di scope e primitive.

Il caso classico รจ un binding inserito all'interno di una direttiva che crea uno scope figlio, come ng-ripetere, ng-if o ng-switch. Scrittura ng-model="name" lรฌ si crea una copia ombra nell'ambito figlio, quindi il genitore non vede mai la modifica. Collegamento a una proprietร  di un oggetto invece โ€” ng-model="user.name" โ€” mantiene ogni ambito puntato allo stesso riferimento. Questo รจ il motivo per cui gli sviluppatori AngularJS esperti insistono sull'utilizzo del punto in ogni espressione ng-model.

Altre due cause spiegano la maggior parte del resto:

  • Controller o modulo mancante: Se `ng-app` o `ng-controller` sono scritti in modo errato, il binding non visualizza nulla senza generare un errore.
  • Valore modificato al di fuori di AngularJS: un valore impostato da un gestore jQuery o da una callback setTimeout arriva al di fuori del ciclo di digest, quindi la vista non si aggiorna finchรฉ $scope.$apply() piste.

Controllando questi tre elementi si risolve la stragrande maggioranza dei problemi di connessione che sembrano non funzionare.

DOMANDE FREQUENTI

`ng-bind` รจ unidirezionale: stampa un valore del modello in un elemento. `ng-model` รจ bidirezionale e funziona solo sui controlli dei moduli, quindi l'input dell'utente fluisce sia verso il modello che verso l'esterno.

Aggiungi `ng-model-options`, ad esempio `ng-model-options="{ debounce: 500 }"`. AngularJS attende quindi mezzo secondo dopo l'ultima pressione di un tasto prima di aggiornare il modello, il che รจ utile per i campi di ricerca che attivano una richiesta.

In larga misura, sรฌ. Gli assistenti IA riscrivono ng-model come [(ngModel)] e aggiungono l'importazione di FormsModule. I moduli reattivi, i parser personalizzati e le pipeline $formatters necessitano ancora di una revisione manuale, perchรฉ Angular li modella in modo molto diverso.

Gli strumenti di intelligenza artificiale verificano rapidamente i soliti sospetti: un vincolo primitivo all'interno di un ambito figlio, un nome del controller scritto in modo errato e un valore assegnato al di fuori del ciclo di digest. Ognuno di questi casi produce un errore silenzioso anzichรฉ un messaggio di errore nella console.

Solo i valori di input di tipo "number" vengono convertiti in valori numerici. Un controllo di tipo "text" restituisce sempre una stringa, quindi i confronti con === falliscono. Convertire esplicitamente o cambiare il tipo di input.

Riassumi questo post con: