Javascript Ng-model 不更新控制器值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12618342/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Ng-model does not update controller value
提问by alchemication
Probably silly question, but I have my html form with simple input and button:
可能是个愚蠢的问题,但我的 html 表单带有简单的输入和按钮:
<input type="text" ng-model="searchText" />
<button ng-click="check()">Check!</button>
{{ searchText }}
Then in the controller (template and controller are called from routeProvider):
然后在控制器中(从 routeProvider 调用模板和控制器):
$scope.check = function () {
console.log($scope.searchText);
}
Why do I see the view updated correctly but undefined in the console when clicking the button?
为什么我在单击按钮时看到视图已正确更新但在控制台中未定义?
Thanks!
谢谢!
Update:
Seems like I have actually solved that issue (before had to come up with some workarounds) with:
Only had to change my property name from searchText
to search.text
, then define empty $scope.search = {};
object in the controller and voila... Have no idea why it's working though ;]
更新:似乎我实际上已经解决了这个问题(之前不得不想出一些解决方法):只需要将我的属性名称从searchText
to更改为search.text
,然后$scope.search = {};
在控制器中定义空对象,瞧......不知道为什么它起作用尽管 ;]
采纳答案by Damax
Controller asversion (recommended)
控制器版本(推荐)
Here the template
这里的模板
<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>
The JS
JS
angular.module('example', [])
.controller('myController', function() {
var vm = this;
vm.check = function () {
console.log(vm.searchText);
};
});
An example: http://codepen.io/Damax/pen/rjawoO
一个例子:http: //codepen.io/Damax/pen/rjawoO
The best will be to use component with Angular 2.x or Angular 1.5 or upper
最好将组件与 Angular 2.x 或 Angular 1.5 或更高版本一起使用
#########Oldway (NOT recommended)
旧方式(不推荐)
This is NOT recommended because a string is a primitive, highly recommended to use an object instead
不推荐这样做,因为字符串是原始的,强烈建议使用对象代替
Try this in your markup
在你的标记中试试这个
<input type="text" ng-model="searchText" />
<button ng-click="check(searchText)">Check!</button>
{{ searchText }}
and this in your controller
这在你的控制器中
$scope.check = function (searchText) {
console.log(searchText);
}
回答by Will Stern
"If you use ng-model, you have to have a dot in there."
Make your model point to an object.property and you'll be good to go.
“如果你使用 ng-model,你必须在那里有一个点。”
让你的模型指向一个 object.property,你就可以开始了。
Controller
控制器
$scope.formData = {};
$scope.check = function () {
console.log($scope.formData.searchText.$modelValue); //works
}
Template
模板
<input ng-model="formData.searchText"/>
<button ng-click="check()">Check!</button>
This happens when child scopes are in play - like child routes or ng-repeats.
The child-scope creates it's own value and a name conflict is born as illustrated here:
See this video clip for more: https://www.youtube.com/watch?v=SBwoFkRjZvE&t=3m15s
当子作用域正在运行时会发生这种情况 - 例如子路由或 ng-repeat。子作用域创建了它自己的值,并产生了名称冲突,如下所示:
有关更多信息,请参见此视频剪辑:https: //www.youtube.com/watch?v=SBwoFkRjZvE&t=3m15s
回答by efirat
In Mastering Web Application Development with AngularJS book p.19, it is written that
在 Mastering Web Application Development with AngularJS book p.19 中,它写道
Avoid direct bindings to scope's properties. Two-way data binding to object's properties (exposed on a scope) is a preferred approach. As a rule of thumb, you should have a dot in an expression provided to the ng-model directive (for example, ng-model="thing.name").
避免直接绑定到作用域的属性。对对象属性(暴露在作用域上)的双向数据绑定是一种首选方法。根据经验,在提供给 ng-model 指令的表达式中应该有一个点(例如,ng-model="thing.name")。
Scopes are just JavaScript objects, and they mimic dom hierarchy. According to JavaScript Prototype Inheritance, scopes properties are separated through scopes. To avoid this, dot notationshould use to bind ng-models.
作用域只是 JavaScript 对象,它们模仿 dom 层次结构。根据JavaScript Prototype Inheritance,范围属性通过范围分隔。为了避免这种情况,应该使用点符号来绑定 ng-models。
回答by Feyyaz
Using this
instead of $scope
works.
使用this
代替$scope
作品。
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:At the time writing this answer, I had much more complicated situation than this. After the comments, I tried to reproduce it to understand why it works, but no luck. I think somehow (don't really know why) a new child scope is generated and this
refers to that scope. But if $scope
is used, it actually refers to the parent $scope because of javascript's lexical scopefeature.
编辑:在写这个答案的时候,我的情况比这复杂得多。在评论之后,我试图重现它以了解它为什么起作用,但没有运气。我认为以某种方式(不知道为什么)会生成一个新的子作用域并this
引用该作用域。但是如果$scope
使用,它实际上是指父 $scope 因为 javascript 的词法范围特性。
Would be great if someone having this problem tests this way and inform us.
如果有人遇到此问题并以这种方式进行测试并通知我们,那就太好了。
回答by Millsionaire
I had the same problem and it was due to me not declaring the blank object first at the top of my controller:
我遇到了同样的问题,这是因为我没有先在控制器顶部声明空白对象:
$scope.model = {}
<input ng-model="model.firstProperty">
Hope this will works for you!
希望这对你有用!
回答by Roger Jin
I came across the same issue when dealing with a non-trivial view (there are nested scopes). And finally discovered this is a known tricky thing when developing AngularJS application due to the nature of prototype-based inheritance of java-script. AngularJS nested scopes are created through this mechanism. And value created from ng-model is placed in children scope, not saying parent scope (maybe the one injected into controller) won't see the value, the value will also shadow any property with same name defined in parent scope if not use dot to enforce a prototype reference access. For more details, checkout the online video specific to illustrate this issue, http://egghead.io/video/angularjs-the-dot/and comments following up it.
在处理非平凡视图(有嵌套作用域)时,我遇到了同样的问题。最终发现这是在开发 AngularJS 应用程序时,由于 java-script 的基于原型继承的性质,这是一个众所周知的棘手的事情。AngularJS 嵌套作用域是通过这种机制创建的。并且从 ng-model 创建的值被放置在子作用域中,并不是说父作用域(可能注入控制器的那个)不会看到该值,如果不使用点,该值也会隐藏在父作用域中定义的任何同名属性强制原型引用访问。有关更多详细信息,请查看特定于说明此问题的在线视频http://egghead.io/video/angularjs-the-dot/和后续评论。
回答by ganaraj
Have a look at this fiddle http://jsfiddle.net/ganarajpr/MSjqL/
看看这个小提琴http://jsfiddle.net/ganarajpr/MSjqL/
I have ( I assume! ) done exactly what you were doing and it seems to be working. Can you check what is not working here for you?
我已经(我假设!)完全完成了你正在做的事情并且它似乎正在起作用。你能检查一下什么对你不起作用吗?
回答by Eric Herlitz
Since no one mentioned this the problem can be resolved by adding $parent
to the bound property
由于没有人提到这一点,因此可以通过添加$parent
绑定属性来解决问题
<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>
And the controller
和控制器
app.controller("LoginController", ['$scope', function ($scope) {
$scope.ssn = '';
$scope.BankLogin = function () {
console.log($scope.ssn); // works!
};
}]);
回答by Plici Stéphane
For me the problem was solved by stocking my datas into an object (here "datas").
对我来说,问题是通过将我的数据存入一个对象(这里是“数据”)来解决的。
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'
}
});
I Hop it will help
我跳它会有所帮助
回答by Hike Nalbandyan
I had the same problem.
The proper way would be setting the 'searchText' to be a property inside an object.
我有同样的问题。
正确的方法是将“searchText”设置为对象内的属性。
But what if I want to leave it as it is, a string? well, I tried every single method mentioned here, nothing worked.
But then I noticed that the problem is only in the initiation, so I've just set the value attribute and it worked.
但是如果我想保持原样,一个字符串怎么办?好吧,我尝试了这里提到的每一种方法,但没有任何效果。
但是后来我注意到问题仅在于启动,所以我刚刚设置了 value 属性并且它起作用了。
<input type="text" ng-model="searchText" value={{searchText}} />
This way the value is just set to '$scope.searchText' value and it's being updated when the input value changes.
这样,该值只是设置为 '$scope.searchText' 值,并且在输入值更改时会更新它。
I know it's a workaround, but it worked for me..
我知道这是一种解决方法,但它对我有用..