Hoe “ng-model” te gebruiken in AngularJS met VOORBEELDEN

⚡ Slimme samenvatting

ng-model in AngularJS koppelt een invoerbesturingselement rechtstreeks aan een eigenschap van $scope, keeping De weergave en het model zijn in beide richtingen gesynchroniseerd. De onderstaande secties behandelen het attribuut, drie werkende voorbeelden en de meest voorkomende fouten die beginners tegenkomen.

  • 🔗 Tweewegbinding: ng-model plaatst gebruikersinvoer in de $scope-eigenschap en stuurt wijzigingen in de controller automatisch terug naar de besturingselementen.
  • 📝 Tekstgebiedbinding: Koppel een tekenreeks met meerdere regels aan een textarea en gebruik de escape-sequentie \n om regeleinden af ​​te dwingen in de weergegeven waarde.
  • ☑️ Status van het selectievakje: Een checkbox die gekoppeld is aan ng-model slaat een booleanwaarde op, dus als 'true' wordt de box aangevinkt en als 'false' blijft deze leeg.
  • 📋 Keuzelijsten: Vul een select-element met ng-options en koppel het gekozen item aan een aparte modeleigenschap.
  • ⚠️ Veelvoorkomende storing: Als een select-element gekoppeld wordt aan hetzelfde object dat de optietekst levert, wordt dat object bij de eerste selectie overschreven.
  • Validatiehaken: ng-model voegt ng-pristine, ng-dirty, ng-valid en ng-invalid klassen toe die voorwaardelijke styling en vormcontroles aansturen.

Wat is ng-model in AngularJS?

`ng-model` is een directive in AngularJS die het model vertegenwoordigt. Het primaire doel ervan is om de "view" aan het "model" te koppelen. Alles wat de gebruiker in een besturingselement typt, wordt direct in een eigenschap van het model opgeslagen. $scopeEn alles wat de controller naar die eigenschap schrijft, wordt direct teruggestuurd naar de controller.

Stel bijvoorbeeld dat u een eenvoudige pagina aan de eindgebruiker wilt presenteren, zoals hieronder weergegeven, waarop de gebruiker wordt gevraagd zijn of haar voornaam en achternaam in tekstvakken in te voeren. Vervolgens wilt u ervoor zorgen dat de ingevoerde informatie in uw datamodel wordt opgeslagen.

Je kunt de `ng-model` directive gebruiken om de tekstvelden "Voornaam" en "Achternaam" te koppelen aan je datamodel. De directive zorgt ervoor dat de data in de "view" en die van je "model" altijd synchroon blijven, zonder dat je ook maar één regel code voor eventhandling nodig hebt.

⚠️ Versie-opmerking: AngularJS (de 1.x-versie) heeft op 31 december 2021 het einde van zijn levenscyclus bereikt en ontvangt geen beveiligingspatches meer. De onderstaande voorbeelden werken nog steeds, maar in moderne Angular wordt dezelfde tweewegbinding als volgt geschreven: [(ngModel)] en vereist de FormsModule.

Het ng-modelkenmerk

Zoals in het vorige gedeelte is besproken, wordt het ng-model-attribuut gebruikt om de gegevens in uw model te koppelen aan de weergave die aan de gebruiker wordt getoond.

Het ng-model attribuut wordt gebruikt voor,

  1. Het koppelen van besturingselementen zoals invoervelden, tekstvakken en selectie-elementen in de weergave aan het model.
  2. Het toevoegen van een validatiefunctie — bijvoorbeeld een validatie aan een tekstvak zodat alleen cijfers kunnen worden ingevoerd.
  3. Het behouden van de status van de besturing. Met status bedoelen we dat de besturing en de gegevens altijd synchroon blijven: als de waarde van de gegevens verandert, verandert de waarde in de besturing automatisch mee, en omgekeerd.
  4. Die status weergeven als CSS-klassen. AngularJS voegt hieraan toe ng-pristine, ng-dirty, ng-valid en ng-invalid voor elk besturingselement dat een ng-model bevat, wat het voorwaardelijk stylen van formulieren zo eenvoudig maakt.

Nu het kenmerk duidelijk is, is de volgende stap om het toe te passen op de drie besturingstypen die u het vaakst zult tegenkomen.

Hoe het ng-model te gebruiken

1) Tekstgebied

De tekstgebiedtag wordt gebruikt om een ​​besturingselement voor tekstinvoer met meerdere regels te definiëren. Het tekstgebied kan een onbeperkt aantal tekens bevatten en de tekst wordt weergegeven in een lettertype met een vaste breedte.

Laten we nu eens kijken naar een eenvoudig voorbeeld van hoe we de `ng-model` directive aan een tekstveld kunnen toevoegen. In dit voorbeeld willen we laten zien hoe we een meerregelige tekenreeks vanuit de controller naar de view kunnen doorgeven en die waarde aan het tekstveld kunnen koppelen.

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

  1. De ng-modelrichtlijn koppelt de lidvariabele genaamd "p"Description” naar het “textarea”-besturingselement. De “pDescriptDe variabele "ion" bevat de tekst die wordt doorgegeven aan het tekstveld. rows="4" en cols="50" Attributen zorgen er simpelweg voor dat het besturingselement de juiste grootte krijgt, zodat de tekst met meerdere regels correct wordt weergegeven.
  2. De lidvariabele “pDescriptAan "ion" wordt een waarde met meerdere regels toegekend. \n De escape-sequentie binnen de tekenreeks zorgt ervoor dat de tekst op een tweede regel terechtkomt wanneer het tekstveld deze weergeeft.

Output:

Uit de uitvoer blijkt duidelijk dat de meerregelige tekst die in de controller is toegewezen, in het tekstveld wordt weergegeven, precies op de plek waar de tekst over twee regels is verdeeld. \n zit.

2) Invoerelementen

De ng-model-richtlijn werkt ook met gewone invoerelementen. Hieronder koppelen we een tekstvak en twee selectievakjes tegelijk, zodat je kunt zien hoe ng-model een tekenreeks en een booleaanse waarde naast elkaar verwerkt.

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

  1. De ng-model-richtlijn koppelt de lidvariabele "pname" aan het tekstinvoerveld en de eigenschappen Topic.Controller en Topic.Models naar de twee selectievakjes.
  2. In de controller krijgt “pname” de tekenreeks “Guru99”, en het “Topic”-object krijgt twee booleaanse leden. Een checkbox die is gekoppeld aan ng-model leest en schrijft altijd een booleaanse waarde, daarom true geeft het vakje aan als aangevinkt en false laat het duidelijk.

Output:

Van de uitvoer,

  • Het is duidelijk te zien dat de waarde die aan de is toegekend pname variabele is “Guru99 ".
  • Aangezien de eerste grenswaarde trueHet selectievakje voor de controller is aangevinkt. Evenzo, aangezien de tweede waarde falseHet selectievakje voor "Modellen" is niet aangevinkt.

3) Selecteer een element uit de vervolgkeuzelijst

De ng-model-richtlijn kan ook worden toegepast op het select-element, zodat het item dat de gebruiker kiest, in het model wordt opgeslagen.

Hier hebben we een tekstinvoerveld met de naam "Guru99”, en een selectielijst met twee lijstitems, “Controller” en “Models”.

⚠️ Correctie: De bovenstaande schermafbeelding toont de oorspronkelijke code, waarbij het select-element aan hetzelfde element was gekoppeld. Topics Het object dat de optietekst leverde. Zodra een gebruiker een optie selecteert, overschrijft AngularJS deze tekst. Topics waarbij de geselecteerde tekenreeks en beide opties verdwijnen. De gecorrigeerde lijst hieronder behoudt de lijst in één eigenschap en de selectie in een andere, en gebruikt ng-options om de lijst samen te stellen.

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

  1. Het tekstinvoerveld is gekoppeld aan pNameen het select-element is gebonden aan selectedTopicOmdat de selectbox een eigen model-eigenschap heeft, wordt de lijst zelf nooit gewijzigd als er een optie wordt gekozen.
  2. De Topics De array bevat de twee waarden "Controller" en "Models". ng-options De expressie doorloopt de array en geeft één optie per item weer, dus het toevoegen van een derde onderwerp vereist geen wijziging in de markup.
  3. selectedTopic is standaard ingesteld op de eerste optie, waardoor het dropdownmenu met een logische standaardwaarde opent in plaats van een lege rij.

Output:

Uit de uitvoer blijkt dat de waarde die is toegekend aan de pName variabele is “Guru99”, en het selectieveld biedt de opties “Controller” en “Modellen”. Afgezien van de werkende voorbeelden, weigeren bindingen soms te worden bijgewerkt, en het is de moeite waard om de redenen hiervoor te kennen.

Waarom ng-model bindingen soms mislukken

De meeste gemelde problemen met ng-model zijn geen bugs in AngularJS, maar gevolgen van de manier waarop scopes en primitieve gegevenstypen werken.

Het klassieke voorbeeld is een binding die binnen een richtlijn wordt geplaatst en een subbereik creëert, zoals bijvoorbeeld: ng-herhalenng-if of ng-switch. Schrijven ng-model="name" Hierdoor wordt een schaduwkopie in het onderliggende bereik gemaakt, waardoor het bovenliggende bereik de bewerking nooit ziet. Binden aan een eigenschap van een object is in plaats daarvan een betere optie. ng-model="user.name" — zorgt ervoor dat elke scope naar dezelfde referentie blijft verwijzen. Dit is de reden waarom ervaren AngularJS-ontwikkelaars aandringen op een punt in elke ng-model-expressie.

Twee andere oorzaken verklaren het grootste deel van de rest:

  • Ontbrekende controller of module: Als ng-app of ng-controller verkeerd gespeld is, zal de binding stilzwijgend niets weergeven in plaats van een foutmelding te geven.
  • Waarde gewijzigd buiten AngularJS: Als een waarde die is ingesteld door een jQuery-handler of een setTimeout-callback buiten de digest-cyclus valt, wordt de weergave pas vernieuwd nadat... $scope.$apply() runs.

Door die drie dingen te controleren, worden de meeste bindingsproblemen die niet lijken te werken opgelost.

Veelgestelde vragen

ng-bind werkt eenrichtingsverkeer: het print een modelwaarde in een element. ng-model werkt tweerichtingsverkeer en is alleen geschikt voor formulierbesturingselementen, waardoor gebruikersinvoer zowel terug naar het model als eruit kan worden opgeslagen.

Voeg bijvoorbeeld `ng-model-options` toe, bijvoorbeeld `ng-model-options=”{ debounce: 500 }”`. AngularJS wacht dan een halve seconde na de laatste toetsaanslag voordat het model wordt bijgewerkt. Dit is handig voor zoekvelden die een verzoek activeren.

Grotendeels wel. AI-assistenten herschrijven ng-model als [(ngModel)] en voegen de FormsModule-import toe. Reactieve formulieren, aangepaste parsers en $formatters-pipelines vereisen nog steeds handmatige controle, omdat Angular ze op een heel andere manier modelleert.

AI-tools controleren snel de meest voorkomende verdachten: een primitieve waarde die binnen een subbereik is gebonden, een verkeerd gespelde controllernaam en een waarde die buiten de digest-cyclus is toegewezen. Elk van deze gevallen leidt tot een stille fout in plaats van een consolefout.

Alleen invoer van het type "number" wordt omgezet naar een numerieke waarde. Een invoer van het type "text" levert altijd een tekenreeks op, waardoor vergelijkingen met === mislukken. Converteer expliciet of wijzig het invoertype.

Vat dit bericht samen met: