Hur man använder "ng-model" i AngularJS med EXEMPEL

⚡ Smart sammanfattning

ng-modellen i AngularJS binder en inmatningskontroll direkt till en egenskap på $scope, keeping vyn och modellen synkroniserade i båda riktningarna. Avsnitten nedan behandlar attributet, tre fungerande exempel och de fel som nybörjare stöter på oftast.

  • 🔗 Tvåvägsbindning: ng-model skickar användarinmatning till $scope-egenskapen och skickar automatiskt tillbaka ändringar i kontrollenheten till kontrollen.
  • 📝 Textområdesbindning: Bind en flerradig sträng till ett textområde och använd escape-sekvensen \n för att tvinga fram radbrytningar i det renderade värdet.
  • ☑️ Kryssrutans status: En kryssruta bunden med ng-model lagrar ett booleskt värde, så true gör rutan markerad och false lämnar den tom.
  • 📋 Rullgardinsmenyer: Fyll ett select-element med ng-options och bind det valda objektet till en separat modellengenskap.
  • ⚠️ Vanligt fel: Att binda en select till samma objekt som anger dess alternativtext skrivs över det objektet i den första selecten.
  • 🛠️ Valideringskrokar: ng-modellen lägger till ng-orörda, ng-smutsiga, ng-giltiga och ng-ogiltiga klasser som driver villkorlig styling och formkontroller.

Vad är ng-modell i AngularJS?

ng-model är ett direktiv i AngularJS som representerar modellen, och dess primära syfte är att binda "vyn" till "modellen". Allt som användaren skriver in i en kontroll skrivs direkt in i en egenskap på $scope, och vad som helst som kontrollanten skriver till den egenskapen skickas direkt tillbaka till kontrollen.

Anta till exempel att du vill presentera en enkel sida för slutanvändaren, likt den som visas nedan, där användaren ombeds att ange "Förnamn" och "Efternamn" i textrutor. Och sedan vill du se till att du lagrar den information som användaren har angett i din datamodell.

Du kan använda ng-model-direktivet för att mappa textrutefälten "Förnamn" och "Efternamn" till din datamodell. Direktivet säkerställer att data i "vyn" och din "modell" hålls synkroniserade hela tiden, utan en enda rad händelsehanteringskod.

⚠️ Versionsinformation: AngularJS (1.x-grenen) nådde slutet av sin livscykel den 31 december 2021 och får inte längre säkerhetsuppdateringar. Exemplen nedan körs fortfarande, men i moderna Angular skrivs samma tvåvägsbindning som [(ngModel)] och kräver FormsModule.

ng-modellens attribut

Som diskuterats i avsnittet ovan används attributet ng-model för att binda data i din modell till den vy som presenteras för användaren.

Attributet ng-model används för,

  1. Bindande kontroller som inmatning, textområde och val av element i vyn i modellen.
  2. Tillhandahålla ett valideringsbeteende — till exempel kan en validering läggas till i en textruta så att endast numeriska tecken kan anges.
  3. Bibehålla kontrollens tillstånd. Med tillstånd menar vi att kontrollen och data alltid hålls synkroniserade: om datavärdet ändras ändras värdet i kontrollen automatiskt, och vice versa.
  4. Exponerar det tillståndet som CSS-klasser. AngularJS lägger till ng-pristine, ng-dirty, ng-valid och ng-invalid till varje kontroll som bär en ng-modell, vilket är det som gör villkorlig formatering av formulär enkel.

När attributet är förstått är nästa steg att tillämpa det på de tre kontrolltyper du kommer att stöta på oftast.

Hur man använder ng-modellen

1) Textområde

Textområdestaggen används för att definiera en textinmatningskontroll med flera rader. Textområdet kan innehålla ett obegränsat antal tecken, och texten återges i ett teckensnitt med fast bredd.

Så låt oss nu titta på ett enkelt exempel på hur vi kan lägga till ng-model-direktivet till en textområdeskontroll. I det här exemplet vill vi visa hur vi kan skicka en flerradig sträng från kontrollenheten till vyn och koppla det värdet till textområdeskontrollen.

<!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 Förklaring:

  1. Ocuco-landskapet ng-modelldirektivet bifogar medlemsvariabeln som heter "p"Description” till kontrollen ”textarea”. Den ”pDescriptVariabeln ”ion” innehåller texten som skickas vidare till textområdeskontrollen. Den rows="4" och cols="50" attribut justerar helt enkelt storleken på kontrollen så att texten med flera rader visas korrekt.
  2. Medlemsvariabeln "p"Descript"jon" tilldelas ett värde på flera rader. Den \n Escape-sekvensen inuti strängen är det som tvingar texten till en andra rad när textarea renderar den.

Produktion:

Av utdata framgår det tydligt att den flerradiga texten som tilldelats i kontrollenheten visas i textområdeskontrollen, uppdelad på två rader exakt där \n sitter.

2) Ingångselement

Direktivet ng-model fungerar även med vanliga inmatningselement. Nedan binder vi en textruta och två kryssrutor samtidigt, så att du kan se hur ng-model hanterar ett strängvärde och ett booleskt värde sida vid sida.

<!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 Förklaring:

  1. Direktivet ng-model kopplar medlemsvariabeln "pname" till textinmatningskontrollen, och egenskaperna Topic.Controller och Topic.Models till de två kryssrutekontrollerna.
  2. I kontrollenheten ges "pname" strängen "Guru99”, och objektet ”Topic” ges två booleska medlemmar. En kryssruta bunden med ng-model läser och skriver alltid en boolesk värde, vilket är anledningen till true återger rutan som markerad och false lämnar det klart.

Produktion:

Från utgången,

  • Det kan tydligt ses att det värde som tilldelats pname variabeln är "Guru99. "
  • Eftersom det första bundna värdet är true, kryssrutan är markerad för kryssrutan "Kontrollör". Likaså, eftersom det andra värdet är false, kryssrutan är inte markerad för kryssrutan ”Modeller”.

3) Välj element från rullgardinsmenyn

Direktivet ng-model kan också tillämpas på select-elementet, så att det objekt som användaren väljer lagras i modellen.

Här kommer vi att ha en textinmatning som innehåller namnet "Guru99”, och en urvalslista med två listobjekt, ”Styrenhet” och ”Modeller”.

⚠️ Rättelse: Skärmdumpen ovan visar den ursprungliga listan, som band select-elementet till exakt samma Topics objektet som levererade alternativtexten. I det ögonblick en användare väljer ett alternativ skriver AngularJS över Topics med den valda strängen och båda alternativen försvinner. Den korrigerade listan nedan behåller listan i en egenskap och valet i en annan, och använder ng-options att bygga listan.

<!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 Förklaring:

  1. Textinmatningen är bunden till pName, och select-elementet är bundet till selectedTopicEftersom select har sin egen model-egenskap, störs aldrig själva listan av att välja ett alternativ.
  2. Ocuco-landskapet Topics Arrayen innehåller de två värdena "Controller" och "Models". ng-options uttrycket använder den arrayen och renderar ett alternativ per post, så att lägga till ett tredje ämne kräver ingen ändring av markupen.
  3. selectedTopic är förinställd på den första posten, vilket gör att rullgardinsmenyn öppnas med en rimlig standard istället för en tom rad.

Produktion:

Från utdata kan man se att värdet som tilldelats pName variabeln är "Guru99”, och select-kontrollen erbjuder alternativen ”Controller” och ”Models”. Bortsett från arbetsexempel vägrar bindningar ibland att uppdateras, och orsakerna är värda att känna till.

Varför ng-modellbindningar ibland misslyckas

De flesta rapporterade ng-modellproblem är inte buggar i AngularJS utan konsekvenser av hur scopes och primitiver fungerar.

Det klassiska fallet är en bindning placerad inuti ett direktiv som skapar ett underordnat scope, till exempel ng-upprepa, ng-if eller ng-switch. Skrivande ng-model="name" där skapas en skuggkopia på det underordnade omfånget, så att föräldern aldrig ser redigeringen. Bindning till en egenskap hos ett objekt istället — ng-model="user.name" — håller varje scope pekande mot samma referens. Det är anledningen till att erfarna AngularJS-utvecklare insisterar på en punkt i varje ng-modelluttryck.

Två ytterligare orsaker står för det mesta av resten:

  • Saknad styrenhet eller modul: Om ng-app eller ng-controller är felstavat, renderar bindningen ingenting i tysthet snarare än att generera ett fel.
  • Värde ändrat utanför AngularJS: Ett värde som anges från en jQuery-hanterare eller ett setTimeout-återanrop hamnar utanför digestcykeln, så vyn uppdateras inte förrän $scope.$apply() körningar.

Att kontrollera dessa tre saker löser den stora majoriteten av bindningar som verkar inte fungera.

Vanliga frågor

ng-bind är enkelriktad: den skriver ut ett modellvärde i ett element. ng-model är tvåvägs och fungerar bara på formulärkontroller, så användarinmatning flödar tillbaka in i modellen såväl som ut ur den.

Lägg till ng-model-options, till exempel ng-model-options=”{ debounce: 500 }”. AngularJS väntar sedan en halv sekund efter den sista tangenttryckningen innan modellen uppdateras, vilket är användbart för sökrutor som utlöser en begäran.

I stort sett, ja. AI-assistenter skriver om ng-modellen till [(ngModel)] och lägger till FormsModule-importen. Reaktiva formulär, anpassade parsers och $formatters-pipelines behöver fortfarande granskas manuellt, eftersom Angular modellerar dem väldigt olika.

AI-verktyg kontrollerar de vanliga misstänkta snabbt: en primitiv gräns inuti ett underordnat omfång, ett felstavat kontrollnamn och ett värde som tilldelats utanför digestcykeln. Var och en producerar ett tyst fel snarare än ett konsolfel.

Endast indata type="number" tolkas till ett numeriskt värde. En type="text"-kontroll ger alltid en sträng, så jämförelser med === misslyckas. Konvertera explicit eller byt indatatyp.

Sammanfatta detta inlägg med: