Modèle d'entrée JS angulaire à partir des valeurs par défaut

dire que vous avez un formulaire qui a des valeurs chargées à partir de la base de données. Comment initialiser ng-model?

exemple:

<input name="card[description]" ng-model="card.description" value="Visa-4242">

dans mon contrôleur, $ scope.la carte n'est pas définie au départ. Est-il un moyen en plus de faire quelque chose comme ça?

$scope.card = {
  description: $('myinput').val()
}
126
demandé sur Calvin Froedge 2012-12-07 23:27:00

14 réponses

ceci est une erreur courante dans les nouvelles applications angulaires. Vous ne voulez pas écrire vos valeurs dans votre HTML sur le serveur si vous pouvez l'éviter. Si c'est le cas, si vous pouvez éviter que votre serveur ne rende HTML, c'est d'autant mieux.

Idéalement, vous voulez envoyer vos modèles HTML angulaires, puis tirer vers le bas vos valeurs via $http dans JSON et les mettre dans votre portée.

alors, si possible, faites ceci:

app.controller('MyController', function($scope, $http) {
    $http.get('/getCardInfo.php', function(data) {
       $scope.card = data;
    });
});

<input type="text" ng-model="card.description" />

si vous devez absolument rendre vos valeurs dans votre HTML à partir de votre serveur, vous pouvez les mettre dans une variable globale et y accéder avec $window:

dans l'en-tête de votre page vous écririez:

<head>
   <script>
       window.card = { description: 'foo' };
   </script>
</head>

et puis dans votre contrôleur vous l'obtiendriez comme ça:

app.controller('MyController', function($scope, $window) {
   $scope.card = $window.card;
});

j'espère que ça aidera.

135
répondu Ben Lesh 2012-12-07 21:24:44

si vous ne pouvez pas retravailler votre application pour faire ce que @blesh suggère (tirer les données JSON vers le bas avec $http ou $resource et peupler $scope), vous pouvez utiliser ng-init à la place:

<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">

Voir aussi AngularJS - Valeur de l'attribut sur une zone de texte d'entrée est ignoré lorsqu'il y a un ng-modèle utilisé?

236
répondu Mark Rajcok 2017-05-23 12:18:24

il s'agit d'un correctif évidemment absent, mais facilement ajouté pour AngularJS. Il suffit d'écrire une directive rapide pour définir la valeur du modèle à partir du champ d'entrée.

<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>

voici ma version:

var app = angular.module('forms', []);

app.directive('ngInitial', function() {
  return {
    restrict: 'A',
    controller: [
      '$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) {
        var getter, setter, val;
        val = $attrs.ngInitial || $attrs.value;
        getter = $parse($attrs.ngModel);
        setter = getter.assign;
        setter($scope, val);
      }
    ]
  };
});
60
répondu Kevin Stone 2013-11-13 07:39:56

IMHO la meilleure solution est la directive @ Kevin Stone, mais j'ai dû la mettre à jour pour fonctionner dans toutes les conditions (F. E. select, textarea), et celui-ci fonctionne à coup sûr:

    angular.module('app').directive('ngInitial', function($parse) {
        return {
            restrict: "A",
            compile: function($element, $attrs) {
                var initialValue = $attrs.value || $element.val();
                return {
                    pre: function($scope, $element, $attrs) {
                        $parse($attrs.ngModel).assign($scope, initialValue);
                    }
                }
            }
        }
    });
12
répondu jtompl 2014-02-13 14:22:20

vous pouvez utiliser une directive personnalisée (avec le soutien de textarea, select, radio et checkbox), consultez ce billet de blog https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form-fields-attributes / .

7
répondu user1519240 2016-12-12 18:57:20

vous pouvez également utiliser dans votre code HTML: ng-init="card.description = 12345"

Il n'est pas recommandé par Angulaire, et comme mentionné ci-dessus, vous devez utiliser exclusivement votre contrôleur.

Mais ça fonctionne :)

6
répondu koxon 2014-10-16 04:30:25

j'ai une approche simple, parce que j'ai quelques validations lourdes et des masques dans mes formes. Ainsi, j'ai utilisé jquery pour obtenir ma valeur à nouveau et lancer l'événement "change" en validations:

$('#myidelement').val('123');
$('#myidelement').trigger( "change");
4
répondu Guilherme Redmer Machado 2016-01-18 01:39:09

comme d'autres l'ont souligné, il n'est pas de bonne pratique d'initialiser les données sur les opinions. Toutefois, il est recommandé d'initialiser les données sur les contrôleurs. (voir http://docs.angularjs.org/guide/controller )

pour que vous puissiez écrire

<input name="card[description]" ng-model="card.description">

et

$scope.card = { description: 'Visa-4242' };

$http.get('/getCardInfo.php', function(data) {
   $scope.card = data;
});

de cette façon les vues ne contiennent pas de données, et le contrôleur initialise la valeur pendant que les valeurs réelles sont chargées.

3
répondu Jkarttunen 2014-03-13 12:54:31

si vous aimez L'approche de Kevin Stone au-dessus de https://stackoverflow.com/a/17823590/584761 envisagez une approche plus simple en écrivant des directives pour des tags spécifiques tels que "input".

app.directive('input', function ($parse) {
    return {
        restrict: 'E',
        require: '?ngModel',
        link: function (scope, element, attrs) {
            if (attrs.ngModel) {
                val = attrs.value || element.text();
                $parse(attrs.ngModel).assign(scope, val);
            }
        }
    }; });

si vous empruntez cette voie, vous n'aurez pas à vous soucier d'ajouter des initiales ng à chaque étiquette. Il définit automatiquement la valeur du modèle à l'attribut valeur de la balise. Si vous ne définissez pas la valeur de l'attribut par défaut est une chaîne vide.

3
répondu coder 2017-05-23 12:10:47

Voici une approche centrée sur le serveur:

<html ng-app="project">
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <script>
        // Create your module
        var dependencies = [];
        var app = angular.module('project', dependencies);

        // Create a 'defaults' service
        app.value("defaults", /* your server-side JSON here */);

        // Create a controller that uses the service
        app.controller('PageController', function(defaults, $scope) {
            // Populate your model with the service
            $scope.card = defaults;
        });
    </script>

    <body>
        <div ng-controller="PageController">
            <!-- Bind with the standard ng-model approach -->
            <input type="text" ng-model="card.description">
        </div>
    </body>
</html>

c'est la même idée de base que les réponses plus populaires sur cette question, sauf $fournir.la valeur enregistre un service qui contient vos valeurs par défaut.

donc, sur le serveur, vous pouvez avoir quelque chose comme:

{
    description: "Visa-4242"
}

et mettez-le dans votre page via la technologie côté serveur de votre choix. Voici L'essentiel: https://gist.github.com/exclsr/c8c391d16319b2d31a43

3
répondu exclsr 2014-09-04 01:33:51

celui-ci est une version plus générique des idées mentionnées ci-dessus... Il vérifie simplement si il n'y a aucune valeur dans le modèle, et si non, il définit la valeur du modèle.

JS:

function defaultValueDirective() {
    return {
        restrict: 'A',
        controller: [
            '$scope', '$attrs', '$parse',
            function ($scope, $attrs, $parse) {
                var getter = $parse($attrs.ngModel);
                var setter = getter.assign;
                var value = getter();
                if (value === undefined || value === null) {
                    var defaultValueGetter = $parse($attrs.defaultValue);
                    setter($scope, defaultValueGetter());
                }
            }
        ]
    }
}

HTML (exemple d'utilisation):

<select class="form-control"
        ng-options="v for (i, v) in compressionMethods"
        ng-model="action.parameters.Method"
        default-value="'LZMA2'"></select>
1
répondu Eitan H.S. 2016-01-17 22:12:19

j'ai essayé ce que @Mark Rajcok a suggéré. Son travail pour les valeurs String (Visa-4242). Veuillez vous référer à cette violon .

du violon:

la même chose qui est fait dans le violon peut être fait en utilisant ng-repeat , que tout le monde pourrait recommander. Mais après avoir lu la réponse donnée par @Mark Rajcok, je voulais juste essayer la même chose pour une forme avec tableau de profils. Les choses marchent bien jusqu'à ce que j'ai le $scope.profil= [{},{}]; code du contrôleur. Si je supprime ce code, je reçois des erreurs. Mais dans les scénarios normaux, Je ne peux pas imprimer $scope.profiles = [{},{}]; comme j'imprime ou l'écho html à partir du serveur. Sera-t-il possible d'exécuter ce qui précède, de la même manière que @Mark Rajcok l'a fait pour les valeurs de chaîne comme <input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'"> , sans avoir à faire écho à la partie JavaScript du serveur.

0
répondu Rajkamal Subramanian 2013-02-20 03:32:49

vient D'ajouter un support pour l'élément select à Ryan Montgomery "fix"

<select class="input-control" ng-model="regCompModel.numberOfEmployeeId" ng-initial>
    <option value="1af38656-a752-4a98-a827-004a0767a52d"> More than 500</option>
    <option value="233a2783-db42-4fdb-b191-0f97d2d9fd43"> Between 250 and 500</option>
    <option value="2bab0669-550c-4555-ae9f-1fdafdb872e5"> Between 100 and 250</option>
    <option value="d471e43b-196c-46e0-9b32-21e24e5469b4"> Between 50 and 100</option>
    <option value="ccdad63f-69be-449f-8b2c-25f844dd19c1"> Between 20 and 50</option>
    <option value="e00637a2-e3e8-4883-9e11-94e58af6e4b7" selected> Less then 20</option>
</select>

app.directive('ngInitial', function () {
return {
    restrict: 'A',
    controller: ['$scope', '$element', '$attrs', '$parse', function ($scope, $element, $attrs, $parse) {
        val = $attrs.sbInitial || $attrs.value || $element.val() || $element.text()
        getter = $parse($attrs.ngModel)
        setter = getter.assign
        setter($scope, val)
    }]
}

});

0
répondu kolesso 2014-02-01 10:45:12

si vous avez la valeur init dans L'URL comme mypage/id , alors dans le contrôleur de l'angle JS vous pouvez utiliser location.pathname pour trouver l'id et l'assigner au modèle que vous voulez.

0
répondu Neon 2014-07-31 06:11:49