web-dev-qa-db-fra.com

AngularJS - L'attribut value d'une zone de texte en entrée est ignoré lorsqu'un modèle ng est utilisé?

Utiliser AngularJS si je définis une valeur de zone de saisie simple à quelque chose comme "bob" ci-dessous. La valeur ne s'affiche pas si l'attribut ng-model est ajouté.

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

Quelqu'un sait-il qu'il est simple de modifier cette entrée par défaut en conservant le ng-model? J'ai essayé d'utiliser un ng-bind avec la valeur par défaut, mais cela ne semble pas fonctionner non plus.

211
HelloWorld

C'est le comportement souhaité, 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';
}
216
Vojta

Vojta a décrit la "méthode angulaire", mais si vous avez vraiment besoin de faire fonctionner cela, @urbanek a récemment publié une solution de contournement utilisant ng-init:

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

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

182
Mark Rajcok

Remplacer la directive d'entrée semble faire l'affaire. J'ai apporté quelques modifications mineures au code de Dan Hunsaker :

  • Ajout d'une vérification de ngModel avant d'essayer d'utiliser $parse().assign() sur des champs sans attributs ngModel.
  • Correction de l'ordre des paramètres de la fonction assign().
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);
      }
    }
  };
});
66
Ivan Breet

La voie angulaire

Pour ce faire, la méthode angulaire correcte consiste à écrire une application à une seule page, AJAX dans le modèle de formulaire, puis à la renseigner de manière dynamique à partir du modèle. Le modèle n'est pas renseigné à partir du formulaire par défaut, car il constitue l'unique source de vérité. Au lieu de cela, Angular ira dans l'autre sens et tentera de renseigner le formulaire à partir du modèle.

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

Si vous avez une application écrite, cela pourrait impliquer des modifications architecturales assez lourdes. Si vous essayez d'utiliser Angular pour améliorer un formulaire existant, plutôt que de construire une application de page entière entière, vous pouvez extraire la valeur du formulaire et la stocker dans la portée au moment du lien à l'aide d'une directive. Angular liera ensuite la valeur de l'étendue au formulaire et le synchronisera.

Utiliser une directive

Vous pouvez utiliser une directive relativement simple pour extraire la valeur du formulaire et la charger dans l'étendue actuelle. Ici, j'ai défini une directive initFromForm.

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;
        if (attrs.type === "number") {val = parseInt(val)}
        $parse(attr).assign(scope, val);
      }
    };
  });

Vous pouvez voir que j'ai défini quelques solutions de repli pour obtenir un nom de modèle. Vous pouvez utiliser cette directive en conjonction avec la directive ngModel ou lier à autre chose que $ scope si vous préférez.

Utilisez-le comme ceci:

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

Notez que cela fonctionnera également avec textareas, et sélectionnez des listes déroulantes.

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

Si vous utilisez la directive AngularJs ngModel, rappelez-vous que la valeur de value attribut ne se lie pas au champ ngModel . Vous devez l’initialiser par vous-même.

<input type="text"
       id="rootFolder"
       ng-init="rootFolders = 'Bob'"
       ng-model="rootFolders"
       disabled="disabled"
       value="Bob"
       size="40"/>
7
Hazarapet Tunanyan

Mise à jour: Ma réponse initiale impliquait que le contrôleur contienne un code sensible au DOM, qui rompt les conventions angulaires en faveur de HTML. @dmackerman a mentionné des directives dans un commentaire sur ma réponse, et cela me manquait complètement jusqu'à maintenant. Avec cette entrée, voici la façon dont {right} __ faire ceci sans rompre les conventions angulaires ou HTML:


Il existe également un moyen d'obtenir à la fois - saisir la valeur de l'élément et l'utiliser pour mettre à jour le modèle dans une directive:

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

et alors:

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 en faire plus avec l'attribut value avant de définir le modèle à sa valeur, notamment en utilisant $parse(attrs.value, scope) pour traiter l'attribut value comme une expression angulaire (bien que j'utiliserais probablement un attribut différent [custom] personnellement, les attributs HTML standard sont systématiquement traités comme des constantes).

En outre, il existe une question similaire sur Rendre les données modèles disponibles dans ng-model qui peut également présenter un intérêt.

7
Dan Hunsaker

Ceci est une légère modification des réponses précédentes ...

Il n'y a pas besoin de $ parse

angular.directive('input', [function () {
  'use strict';

  var directiveDefinitionObject = {
    restrict: 'E',
    require: '?ngModel',
    link: function postLink(scope, iElement, iAttrs, ngModelController) {
      if (iAttrs.value && ngModelController) {
        ngModelController.$setViewValue(iAttrs.value);
      }
    }
  };

  return directiveDefinitionObject;
}]);
5
dale.lotts

Le problème est que vous devez définir le modèle ng sur l'élément parent sur lequel vous souhaitez définir la valeur/valeur ng . Comme mentionné par Angular:

Il est principalement utilisé sur les éléments input [radio] et option. Ainsi, lorsque l'élément est sélectionné, le ngModel de cet élément (ou de son élément parent sélectionné) est défini sur la valeur liée.

Ex: Ceci est un code exécuté:

<div class="col-xs-12 select-checkbox" >
<label style="width: 18em;" ng-model="vm.settingsObj.MarketPeers">
  <input name="radioClick" type="radio"  ng-click="vm.setPeerGrp('market');" 
         ng-value="vm.settingsObj.MarketPeers" 
         style="position:absolute;margin-left: 9px;">
  <div style="margin-left: 35px;color: #717171e8;border-bottom: 0.5px solid #e2e2e2;padding-bottom: 2%;">Hello World</div>
</label>
</div>

Remarque: dans le cas ci-dessus, j’avais déjà la réponse JSON au modèle-ng et la valeur; j’ajoute simplement une autre propriété à l’objet JS en tant que "MarketPeers". Donc, le modèle et la valeur peuvent dépendre du besoin, mais je pense que ce processus aidera à avoir à la fois un modèle et une valeur, mais ne pas les avoir sur le même élément.

0
sg28

Bonjour, vous pouvez essayer les méthodes ci-dessous avec initialize of model.

Ici vous pouvez initialiser ng-model of textbox dans les deux sens

- Avec l'utilisation de ng-init

- Avec l'utilisation de $ scope dans js

<!doctype html>
 <html >
 <head>
        <title>Angular js initalize with ng-init and scope</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
</head>
<body ng-app="app" >
    <h3>Initialize value with ng-init</h3>
    <!-- Initlialize model values with ng-init -->
    <div ng-init="user={fullname:'Bhaskar Bhatt',email:'[email protected]',address:'Ahmedabad'};">
        Name : <input type="text" ng-model="user.fullname" /><br/>
        Email : <input type="text" ng-model="user.email" /><br/>
        Address:<input type="text" ng-model="user.address" /><br/>

    </div>  
    <!-- initialize with js controller scope -->
    <h3>Initialize with js controller</h3>

    <div  ng-controller="alpha">
        Age:<input type="text" name="age" ng-model="user.age" /><br/>
        Experience : <input type="text" name="experience" ng-model="user.exp" /><br/>
        Skills : <input type="text" name="skills" ng-model="user.skills" /><br/>
    </div>  

</body> 
<script type="text/javascript">
        angular.module("app",[])
        .controller("alpha",function($scope){
            $scope.user={};
            $scope.user.age=27;
            $scope.user.exp="4+ years";
            $scope.user.skills="Php,javascript,Jquery,Ajax,Mysql";
        });

     </script>
 </html>                
0
Bhaskar Bhatt

J'ai eu le même problème. Je ne pouvais pas utiliser value="something" pour afficher et éditer . Je devais utiliser la commande ci-dessous dans mon <input> depuis que le modèle était déclaré.

[(ngModel)]=userDataToPass.pinCode

Où j'ai la liste des données dans l'objet userDataToPass et l'élément que j'ai besoin d'afficher et de modifier est pinCode.

Pour la même chose, j'ai mentionné cette vidéo YouTube

0
tkrloltkr