我想让我的服务能够处理任何输入字段。目前我手动编写所有内容,它开始相当于大量的手工工作。有没有办法在调用元素ng-change属性时发送元素对象?然后我可以更改元素ng-class。
HTML:
<input type="text" id="email" data-ng-model="email" data-ng-change="changeEmail()" placeholder="your email here" data-ng-class="emailFormControlColor">
在控制器中:
$scope.changeEmail = function () {
if ($checkInput.checkEmail($scope.email)) {
// email input is good
$scope.emailFormControlColor = 'form-control-success'; // change from error to success
} else {
// email input is bad
if ($scope.emailFormControlColor === 'form-control-success')
$scope.emailFormControlColor = 'form-control-error'; // change from success to error
}
};
服务(这包含在c的控制器参数中):
.service('checkInput', ['$controller', '$window', '$location', function ($controller, $window, $location) {
return {
checkEmail: function (email) {
// <--- I would like to update the ng-class of the focused element here! This would result in me not manually having to write code for each input!
var regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
};
}])
上面的代码就是我现在拥有它的方式。如您所见,我手动更改了$ scope.emailFormControlColor。
想象一下,我有三个输入字段:
<input type="text" id="email1" data-ng-model="email1" data-ng-change="changeEmail()" placeholder="your email here" data-ng-class="emailFormControlColor1">
<input type="text" id="email2" data-ng-model="email2" data-ng-change="changeEmail()" placeholder="your email here" data-ng-class="emailFormControlColor2">
<input type="text" id="email3" data-ng-model="email3" data-ng-change="changeEmail()" placeholder="your email here" data-ng-class="emailFormControlColor3">
如何编写我的服务,以便我手动编写以下内容:
$scope.emailFormControlColor1 = 'form-control-success';
$scope.emailFormControlColor2 = 'form-control-success';
$scope.emailFormControlColor3 = 'form-control-success';
我希望我的问题很明确,否则请说,我会更新它!
答案 0 :(得分:2)
我认为使用指令来解决这个问题更为可取。首先,它被认为是修改控制器或服务中的DOM的反模式。
另一个原因是当您使用指令时,将为您提供使用该指令的DOM元素。这里有一些未经测试的代码可以作为起点使用:
myModule.directive('checkEmail', function() {
require: 'ngModel',
link: function(scope, element, attributes, ngModelController) {
// require that ng-model is used on this element, so you can hook
// into the Angular validator pipeline ...
ngModelController.validators.checkEmail = function(modelValue, viewValue) {
// now return true or false if viewValue is considered valid
var regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
var isValid = regex.test(viewValue);
// but you also have an opportunity to do your DOM manipulation
element.toggleClass('form-control-success', isValid);
element.toggleClass('form-control-error', !isValid);
return isValid;
});
}
});
您可以使用Angular内置的验证系统,而不是像上面那样应用CSS类。您的指令代码与上面相同,除非您不在指令中应用任何CSS类。当指令中的验证代码返回false
时,Angular将使该字段无效......您可以使用此事实在HTML中应用CSS:
<form name="myForm">
<input ng-model="whatever"
name="email"
check-email
ng-class="{'form-control-success': myForm.email.$valid, 'form-control-error': myForm.email.$invalid}">
</form>
以上内容在字段无效时应用CSS,但您也可以在发生特定验证错误时应用它,在此示例中我们将验证器命名为&#34; checkEmail&#34;,这样也可以:< / p>
<form name="myForm">
<input ng-model="whatever"
name="email"
check-email
ng-class="{'form-control-success': !myForm.email.$error.checkEmail, 'form-control-error': myForm.email.$error.checkEmail}">
</form>
答案 1 :(得分:0)
我会创建一个对象,其中包含每封电子邮件所需的所有信息。像这样:
HTML:
<input type="text" id="email0" data-ng-model="emails[0].value" data-ng-change="changeEmail(emails[0])" placeholder="your email here" data-ng-class="emails[0].class">
<input type="text" id="email1" data-ng-model="emails[1].value" data-ng-change="changeEmail(emails[1])" placeholder="your email here" data-ng-class="emails[1].class">
<input type="text" id="email2" data-ng-model="emails[2].value" data-ng-change="changeEmail(emails[2])" placeholder="your email here" data-ng-class="emails[2].class">
JavaScript的:
$scope.emails = [
{ value: '', class: '' },
{ value: '', class: '' },
{ value: '', class: '' },
];
$scope.changeEmail = function (email) {
if ($checkInput.checkEmail(email)) {
// email input is good
email.class = 'form-control-success'; // change from error to success
} else {
// email input is bad
if (email.class === 'form-control-success') {
email.class = 'form-control-error'; // change from success to error
}
}
};
如果合适,您可以使用ng-repeat
之类的内容来避免在HTML中复制/粘贴。
答案 2 :(得分:0)
尽管Sunil D.基本上向我指出代码不正确的答案。下面是使其工作的代码。 http://codepen.io/basickarl/pen/MyoZNB
HTML:
<div ng-app="app" ng-controller="ctrl">
<form name="myForm">
<input ng-model="name" name="name">
<input ng-model="email" name="email" check-email>
</form>
</div>
CSS:
input {
border: 5px;
border-style: solid;
border-color: silver;
}
.input-invalid {
border-color: red;
}
.input-valid {
border-color: lime;
}
JS:
var app = angular.module('app', []);
app.controller('ctrl', ['$scope', function($scope) {
$scope.name = "";
$scope.email = "";
}]);
app.directive('checkEmail', [function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, el, attr, ctrl) {
ctrl.$validators.checkEmail = function(modelVal, viewVal) {
var regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
var isValid = regex.test(viewVal);
el.toggleClass('input-valid', isValid);
el.toggleClass('input-invalid', !isValid);
return isValid;
}
}
}
}]);