Probablement question idiote, mais j'ai mon formulaire HTML avec une simple saisie et un bouton:
<input type="text" ng-model="searchText" />
<button ng-click="check()">Check!</button>
{{ searchText }}
Ensuite, dans le contrôleur (le modèle et le contrôleur sont appelés depuis routeProvider):
$scope.check = function () {
console.log($scope.searchText);
}
Pourquoi la vue est-elle mise à jour correctement mais non définie dans la console lorsque je clique sur le bouton?
Merci!
Mise à jour: On dirait que j'ai en fait résolu ce problème (auparavant, il fallait trouver des solutions) avec: Il suffisait de changer le nom de ma propriété de searchText
à search.text
, puis de définir vide $scope.search = {};
objet dans le contrôleur et le tour est joué ... Je ne sais pas pourquoi cela fonctionne bien;]
Contrôleur en version (recommandé)
Ici le modèle
<div ng-app="example" ng-controller="myController as $ctrl">
<input type="text" ng-model="$ctrl.searchText" />
<button ng-click="$ctrl.check()">Check!</button>
{{ $ctrl.searchText }}
</div>
Le JS
angular.module('example', [])
.controller('myController', function() {
var vm = this;
vm.check = function () {
console.log(vm.searchText);
};
});
Un exemple: http://codepen.io/Damax/pen/rjawoO
Le mieux sera d’utiliser un composant avec Angular 2.x ou Angular 1.5 ou supérieur
Ancien moyen (NON recommandé)
Ceci n'est PAS recommandé car une chaîne est une primitive, il est fortement recommandé d'utiliser un objet à la place.
Essayez ceci dans votre balisage
<input type="text" ng-model="searchText" />
<button ng-click="check(searchText)">Check!</button>
{{ searchText }}
et cela dans votre contrôleur
$scope.check = function (searchText) {
console.log(searchText);
}
"Si vous utilisez ng-model, vous devez y placer un point."
Faites pointer votre modèle vers une propriété objet et vous serez prêt à partir.
Contrôleur
$scope.formData = {};
$scope.check = function () {
console.log($scope.formData.searchText.$modelValue); //works
}
Modèle
<input ng-model="formData.searchText"/>
<button ng-click="check()">Check!</button>
Cela se produit lorsque des gammes enfants sont en jeu, comme des routes enfants ou des répétitions ng. La portée enfant crée sa propre valeur et un conflit de noms est né comme illustré ici :
Voir ce clip vidéo pour en savoir plus: https://www.youtube.com/watch?v=SBwoFkRjZvE&t=3m15s
Dans Mastering Web Application Development avec AngularJS, livre p.19, il est écrit que
Évitez les liaisons directes aux propriétés de l'étendue. La liaison de données bidirectionnelle aux propriétés de l'objet (exposées sur une étendue) est une approche recommandée. En règle générale, vous devez insérer un point dans une expression fournie à la directive ng-model (par exemple, ng-model = "thing.name").
Les portées ne sont que des objets JavaScript, et elles imitent la hiérarchie dom. Selon héritage du prototype JavaScript , les propriétés des portées sont séparées par des portées. Pour éviter cela, la notation par points devrait utiliser pour lier les modèles ng.
Utiliser this
au lieu de $scope
fonctionne.
function AppCtrl($scope){
$scope.searchText = "";
$scope.check = function () {
console.log("You typed '" + this.searchText + "'"); // used 'this' instead of $scope
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="AppCtrl">
<input ng-model="searchText"/>
<button ng-click="check()">Write console log</button>
</div>
</div>
Edit: Au moment d'écrire cette réponse, j'avais une situation beaucoup plus compliquée que celle-là. Après les commentaires, j'ai essayé de le reproduire pour comprendre pourquoi cela fonctionne, mais pas de chance. Je pense en quelque sorte (je ne sais pas vraiment pourquoi) une nouvelle portée enfant est générée et this
fait référence à cette portée. Mais si $scope
est utilisé, il fait en fait référence à la portée de $ parent en raison de la fonctionnalité portée lexicale de javascript.
Ce serait génial si quelqu'un ayant ce problème teste de cette façon et nous en informe.
J'ai eu le même problème et c'est parce que je n'ai pas déclaré l'objet vierge en haut de mon contrôleur:
$scope.model = {}
<input ng-model="model.firstProperty">
J'espère que cela fonctionnera pour vous!
J'ai rencontré le même problème lorsqu'il s'agissait d'une vue non triviale (il y a des portées imbriquées). Et finalement découvert que c’est une chose délicate connue lors du développement d’une application AngularJS en raison de la nature de l’héritage du script Java basé sur un prototype. Les portées imbriquées AngularJS sont créées via ce mécanisme. Et la valeur créée à partir de ng-model est placée dans la portée des enfants. Cela ne signifie pas que la portée parent (peut-être celle injectée dans le contrôleur) ne verra pas la valeur, la valeur occultera également toute propriété du même nom définie dans la portée parent si elle n'est pas utilisée pour appliquer un prototype d'accès de référence. Pour plus de détails, consultez la vidéo en ligne spécifique pour illustrer ce problème, http://egghead.io/video/angularjs-the-dot/ et les commentaires qui ont suivi.
Regardez ce violon http://jsfiddle.net/ganarajpr/MSjqL/
J'ai (je suppose!) Fait exactement ce que vous faisiez et cela semble fonctionner. Pouvez-vous vérifier ce qui ne fonctionne pas ici pour vous?
Comme personne ne l’a mentionné, le problème peut être résolu en ajoutant $parent
à la propriété liée.
<div ng-controller="LoginController">
<input type="text" name="login" class="form-control" ng-model="$parent.ssn" ng-pattern="/\d{6,8}-\d{4}|\d{10,12}/" ng-required="true" />
<button class="button-big" type="submit" ng-click="BankLogin()" ng-disabled="!bankidForm.login.$valid">Logga in</button>
</div>
Et le contrôleur
app.controller("LoginController", ['$scope', function ($scope) {
$scope.ssn = '';
$scope.BankLogin = function () {
console.log($scope.ssn); // works!
};
}]);
Pour moi, le problème a été résolu en stockant mes données dans un objet (ici "données").
NgApp.controller('MyController', function($scope) {
$scope.my_title = ""; // This don't work in ng-click function called
$scope.datas = {
'my_title' : "",
};
$scope.doAction = function() {
console.log($scope.my_title); // bad value
console.log($scope.datas.my_title); // Good Value binded by'ng-model'
}
});
J'espère que ça va aider
Je viens d'avoir ce problème en utilisant un root_controller lié à l'élément body. Ensuite, j'utilisais ng-view avec le routeur angular. Le problème est que angular TOUJOURS crée une nouvelle portée lorsqu'il insère le code HTML dans l'élément ng-view. En conséquence, ma fonction "check" a été définie sur la portée parente de la portée modifiée par mon élément ng-model.
Pour résoudre le problème, utilisez simplement un contrôleur dédié dans le contenu HTML chargé par route.
Vous pouvez le faire pour activer la recherche dans ng-keypress
à saisir pour le texte saisi et dans ng-click
pour l’icône:
<input type="text" ng-model="searchText" ng-keypress="keyEnter(this,$event)" />
<button ng-click="check(searchText)">Check!</button>
in the controller
$scope.search = function (searchText) {
console.log(searchText);
}
$scope.keyEnter = function (serachText,$event) {
var keyCode = $event.which || $event.keyCode;
if (keyCode === 13) {//KeyCode for Enter key
console.log(searchText);
}
}
Je faisais face au même problème ... La solution qui a fonctionné pour moi est d'utiliser ce mot clé ..........
alerte (this.NomModèle);
J'ai eu le même problème.
La bonne façon serait de définir le 'searchText' pour qu'il soit une propriété à l'intérieur d'un objet.
Mais que se passe-t-il si je veux le laisser tel quel, une chaîne? Eh bien, j'ai essayé toutes les méthodes mentionnées ici, rien n'a fonctionné.
Mais ensuite, j'ai remarqué que le problème ne concernait que l'initiation, je viens donc de définir l'attribut value et cela a fonctionné.
<input type="text" ng-model="searchText" value={{searchText}} />
De cette façon, la valeur est simplement définie sur la valeur '$ scope.searchText' et elle est mise à jour lorsque la valeur d'entrée change.
Je sais que c'est une solution de contournement, mais cela a fonctionné pour moi ..