220 votes

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

En utilisant AngularJS si j'ai mis une simple zone de saisie de la valeur à quelque chose comme "bob" ci-dessous. La valeur ne s'affiche pas si l' ng-model attribut est ajouté.

    <input type="text"
           id="rootFolder"
           ng-model="rootFolders"
           disabled="disabled"
           value="Bob"
           size="40"/>

Quelqu'un sait d'un simple contourner par défaut de cette entrée pour quelque chose et de garder l' ng-model? J'ai essayé d'utiliser un ng-bind avec la valeur par défaut, mais qui ne semble pas fonctionner non plus.

224voto

Vojta Points 12058

C'est le comportement désiré, vous devez définir le modèle dans le contrôleur, pas dans la vue.

<div ng-controller="Main">
  <input type="text" ng-model="rootFolders">
</div>


function Main($scope) {
  $scope.rootFolders = 'bob';
}

189voto

Mark Rajcok Points 85912

Vojta décrit le "Angulaire", mais si vous avez vraiment besoin pour faire ce travail, @urbanek a récemment posté une solution de contournement à l'aide de ng-init:

<input type="text" ng-model="rootFolders" ng-init="rootFolders='Bob'" value="Bob">

https://groups.google.com/d/msg/angular/Hn3eztNHFXw/wk3HyOl9fhcJ

68voto

Ivan Breet Points 281

En substituant l'entrée de la directive ne semble pas faire le travail. J'ai fait quelques petites modifications à Dan Hunsakerle code:

  • Ajout d'une vérification pour ngModel avant d'essayer d'utiliser $parse().assign() sur les champs sans une ngModel attributs.
  • Correction de l'affecter() de la fonction param commande.
app.directive('input', function ($parse) {
  return {
    restrict: 'E',
    require: '?ngModel',
    link: function (scope, element, attrs) {
      if (attrs.ngModel && attrs.value) {
        $parse(attrs.ngModel).assign(scope, attrs.value);
      }
    }
  };
});

21voto

superluminary Points 5496

L'angle moyen

Le bon Angulaire de la façon de le faire est d'écrire une page unique application, AJAX dans le modèle de formulaire, puis de le remplir de façon dynamique à partir du modèle. Le modèle n'est pas rempli à partir de la forme par défaut, parce que le modèle est la source unique de la vérité. Au lieu de cela Angulaire va aller de l'autre et essayer de remplir le formulaire à partir du modèle.

Si toutefois, vous n'avez pas le temps de recommencer à partir de zéro

Si vous avez une application écrite, cela peut impliquer quelques-uns assez lourdes modifications architecturales. Si vous essayez d'utiliser Angulaire pour améliorer un formulaire existant, plutôt que de construire toute une page unique application à partir de zéro, vous pouvez tirer la valeur de la forme et de la stocker dans le champ d'application au moment de la liaison à l'aide d'une directive. Angulaire va alors lier la valeur dans le champ d'application de retourner au formulaire et de le synchroniser.

À l'aide d'une directive

Vous pouvez utiliser un moyen relativement simple de la directive de tirer la valeur de la forme et de le charger dans le champ d'application actuel. Ici, j'ai défini un initFromForm directive.

var myApp = angular.module("myApp", ['initFromForm']);

angular.module('initFromForm', [])
  .directive("initFromForm", function ($parse) {
    return {
      link: function (scope, element, attrs) {
        var attr = attrs.initFromForm || attrs.ngModel || element.attrs('name'),
        val = attrs.value;
        $parse(attr).assign(scope, val)
      }
    };
  });

Vous pouvez le voir, j'ai défini un couple de base pour obtenir un nom de modèle. Vous pouvez utiliser cette directive, conjointement avec la ngModel directive, ou se lier à quelque chose d'autre que $portée si vous préférez.

L'utiliser comme ceci:

<input name="test" ng-model="toaster.test" value="hello" init-from-form />
{{toaster.test}}

Remarque cela permettra également de travailler avec ces zones de texte, puis sélectionnez listes déroulantes.

<textarea name="test" ng-model="toaster.test" init-from-form>hello</textarea>
{{toaster.test}}

7voto

Dan Hunsaker Points 63

Mise à jour: Ma réponse originale à cette question consiste le contrôleur de contenir des DOM-connaissance du code, qui rompt Angulaire des conventions en faveur de l'HTML. @dmackerman directives dans un commentaire sur ma réponse, et j'ai complètement oubliée jusqu'à ce que tout à l'heure. Avec cette entrée, voici le droit de la façon de le faire sans casser Angulaire ou HTML conventions:


Il est également possible d'obtenir les deux - saisir la valeur de l'élément et l'utiliser pour mettre à jour le modèle dans la directive:

<div ng-controller="Main">
    <input type="text" id="rootFolder" ng-model="rootFolders" disabled="disabled" value="Bob" size="40" />
</div>

et puis:

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

Vous pouvez bien sûr modifier la directive ci-dessus pour faire plus avec l' value attribut avant de définir le modèle de sa valeur, y compris à l'aide de $parse(attrs.value, scope) pour traiter l' value attribut comme un Angulaire de l'expression (bien que je serais probablement utiliser un autre [personnalisé] attribut pour que, personnellement, de sorte que le standard HTML attributs sont toujours traités comme des constantes).

Aussi, il y a une question similaire sur à Rendre les données basé sur un modèle disponible pour le ng-model qui peut aussi être d'intérêt.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X