AngularJS 使用 ngMessages 从控制器设置表单值
AngularJS set form value from controller with ngMessages
我尝试在 angular 1.5.9 中使用表单,但无法找到满足以下要求的方法:
- 从控制器访问表单数据(绑定
controllerAs
)
- 不要使用
$scope
绑定表单
- 能够从控制器设置默认值
- 能够从控制器更改值
- 能够从控制器访问数据
- 使用 ngMessages 进行验证
我做了一个注释 jsbin 来说明问题和我尝试过的方法,你可以在这里找到它:http://jsbin.com/guzejelula/edit?html,js,output。
除了第 4 个之外,这里的每个要求都在 jsbin 中得到满足,说明为:
this.setLastName = function(name) {
// When doing this while the field is empty, the "required"
// error disappear but the input stays empty.
this.userForm.lastName.$setViewValue(name);
this.userForm.lastName.$validate();
}
我错过了什么?
您需要告诉刚刚更改的视图(输入)呈现自身,以便更改模型值(以便新值显示在表单字段中)。
angular.element('your element id').controller('ngModel').$render()
据我所知,我认为您绑定的模型不正确。
$ctrl.userForm
是您的表单控制器实例。 ngModel 上的 "name" 属性将表单控件(输入)实例公开给表单控制器实例。所以,$ctrl.userForm.lastName
不会是原始模型值,它将是一个具有 ngModelController
函数的对象。
为了pre-populate表单控制器正确,确保ng-model表达式有正确的初始值。目前,您的 ng-model
绑定到 $scope.lastName
。这就是为什么它呈现为空而不是 "toto." 要修复它,您可以将 $scope.lastName = "toto"
添加到您的控制器,但是由于您要避免使用 $scope
,只需定义 this.lastName = 'toto'
并使用 ng-model="$ctrl.lastName"
.
从按钮中,您只需执行 this.lastName = name
。无需自己调用 $render
和 $validate
,因为 Angular 会代表您执行此操作,因为它会检测到模型值的变化。
如果有帮助,我刚刚写了一个 article 来了解 ngModelController
中发生的事情,如果您有兴趣的话。
希望对您有所帮助!
var app = angular.module('jsbin', ['ngMessages']);
app.controller('DemoCtrl', function() {
/**
* Here I would like to set a defaut state form the form.
*
* This object will be replaced by the FormController instance
* as defined in the view by "<form name="$ctrl.userForm">"
* with no regards for its current content.
*/
this.lastName = 'toto';
this.formResults = {};
/**
* I would like to set the value of one or multiple fields
* in the controller.
* Here I try to set "lastName" with no success.
*
* I excepted something like:
* this.userForm.setValues({
* lastName : 'Doe',
* firstName: 'John'
* });
*
* or
*
* this.userForm.setValue('lastName', 'value here');
*
* ...
*/
this.setLastName = function(name) {
// When doing this while the field is empty, the "required"
// error disappear but the input stays empty.
this.lastName = name;
}
/**
* Here a clean way to extract current values of the form would be handy..
* Something like :
* this.userForm.getValues();
*/
this.submit = function(form){
this.formResults = {};
if (form.$valid) {
var values = {};
angular.forEach(form, function (value, key) {
if (typeof(value) === 'object' && value.hasOwnProperty('$modelValue')) {
values[key] = value.$modelValue;
}
});
this.formResults = values;
}
};
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Angular JS</title>
</head>
<body ng-app="jsbin">
<div ng-controller="DemoCtrl as $ctrl">
<form name="$ctrl.userForm" novalidate>
<label>Last Name:</label>
<input name="lastName" ng-model="$ctrl.lastName" required="" minlength="2" type="text">
<ng-messages for="$ctrl.userForm.lastName.$error">
<ng-message when="minlength">Too small!</ng-message>
<ng-message when="required">Required!</ng-message>
</ng-messages>
<button ng-click="$ctrl.submit($ctrl.userForm)">Submit</button>
</form>
<p>
<button ng-click="$ctrl.setLastName('Test')">Set value to "lastName"</button>
</p>
<h2>Results</h2>
{{$ctrl.formResults|json}}
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.9/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.9/angular-messages.js"></script>
</body>
</html>
我尝试在 angular 1.5.9 中使用表单,但无法找到满足以下要求的方法:
- 从控制器访问表单数据(绑定
controllerAs
) - 不要使用
$scope
绑定表单 - 能够从控制器设置默认值
- 能够从控制器更改值
- 能够从控制器访问数据
- 使用 ngMessages 进行验证
我做了一个注释 jsbin 来说明问题和我尝试过的方法,你可以在这里找到它:http://jsbin.com/guzejelula/edit?html,js,output。
除了第 4 个之外,这里的每个要求都在 jsbin 中得到满足,说明为:
this.setLastName = function(name) {
// When doing this while the field is empty, the "required"
// error disappear but the input stays empty.
this.userForm.lastName.$setViewValue(name);
this.userForm.lastName.$validate();
}
我错过了什么?
您需要告诉刚刚更改的视图(输入)呈现自身,以便更改模型值(以便新值显示在表单字段中)。
angular.element('your element id').controller('ngModel').$render()
据我所知,我认为您绑定的模型不正确。
$ctrl.userForm
是您的表单控制器实例。 ngModel 上的 "name" 属性将表单控件(输入)实例公开给表单控制器实例。所以,$ctrl.userForm.lastName
不会是原始模型值,它将是一个具有 ngModelController
函数的对象。
为了pre-populate表单控制器正确,确保ng-model表达式有正确的初始值。目前,您的 ng-model
绑定到 $scope.lastName
。这就是为什么它呈现为空而不是 "toto." 要修复它,您可以将 $scope.lastName = "toto"
添加到您的控制器,但是由于您要避免使用 $scope
,只需定义 this.lastName = 'toto'
并使用 ng-model="$ctrl.lastName"
.
从按钮中,您只需执行 this.lastName = name
。无需自己调用 $render
和 $validate
,因为 Angular 会代表您执行此操作,因为它会检测到模型值的变化。
如果有帮助,我刚刚写了一个 article 来了解 ngModelController
中发生的事情,如果您有兴趣的话。
希望对您有所帮助!
var app = angular.module('jsbin', ['ngMessages']);
app.controller('DemoCtrl', function() {
/**
* Here I would like to set a defaut state form the form.
*
* This object will be replaced by the FormController instance
* as defined in the view by "<form name="$ctrl.userForm">"
* with no regards for its current content.
*/
this.lastName = 'toto';
this.formResults = {};
/**
* I would like to set the value of one or multiple fields
* in the controller.
* Here I try to set "lastName" with no success.
*
* I excepted something like:
* this.userForm.setValues({
* lastName : 'Doe',
* firstName: 'John'
* });
*
* or
*
* this.userForm.setValue('lastName', 'value here');
*
* ...
*/
this.setLastName = function(name) {
// When doing this while the field is empty, the "required"
// error disappear but the input stays empty.
this.lastName = name;
}
/**
* Here a clean way to extract current values of the form would be handy..
* Something like :
* this.userForm.getValues();
*/
this.submit = function(form){
this.formResults = {};
if (form.$valid) {
var values = {};
angular.forEach(form, function (value, key) {
if (typeof(value) === 'object' && value.hasOwnProperty('$modelValue')) {
values[key] = value.$modelValue;
}
});
this.formResults = values;
}
};
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Angular JS</title>
</head>
<body ng-app="jsbin">
<div ng-controller="DemoCtrl as $ctrl">
<form name="$ctrl.userForm" novalidate>
<label>Last Name:</label>
<input name="lastName" ng-model="$ctrl.lastName" required="" minlength="2" type="text">
<ng-messages for="$ctrl.userForm.lastName.$error">
<ng-message when="minlength">Too small!</ng-message>
<ng-message when="required">Required!</ng-message>
</ng-messages>
<button ng-click="$ctrl.submit($ctrl.userForm)">Submit</button>
</form>
<p>
<button ng-click="$ctrl.setLastName('Test')">Set value to "lastName"</button>
</p>
<h2>Results</h2>
{{$ctrl.formResults|json}}
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.9/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.9/angular-messages.js"></script>
</body>
</html>