【发布时间】:2014-01-31 00:33:40
【问题描述】:
我有一个 AngularJS 指令,我用它来试验延迟表单字段验证,无论是在模糊还是在空闲时(一段时间没有输入)。我有两种方法连接起来;一种是在实际输入字段上添加一个类,另一种是在作用域上设置一个状态变量。设置类对于设置字段的样式是可以的,但我更关心的是帮助消息的样式(ng 显示),它位于一个不相关的元素上。另外这个类可以用ng-class添加,所以我想要的方法似乎应该是状态变量属性检查。
我的问题:
- 有没有一种方法可以轻松地从指令中公开 isActive 状态,这样调用者就不必传递外部属性来充当中介?这真的不是外部状态,它都是面向视图的,我只想从 HTML 中干净地访问它。
- $error、$invalid 等是如何附加到元素上并解决的?我可以在用户代码中构建相同的功能吗?即 element.state.active?
<form name="f">
<div class="form-group" ng-class="{'has-error': f.e.$invalid}">
<label>Enter Email Address</label>
<input type="email" class="form-control" name="e" ng-model="user.email" required autofocus active="1500" is-active="state.active"/>
<p class="help-block" ng-show="!state.active && f.e.$error.required">email is required</p>
<p class="help-block" ng-show="!state.active && f.e.$error.email">enter a valid email address</p>
<p class="help-block" ng-show="state.active">typing...</p>
<p class="help-block" ng-show="!state.active && f.$valid">ok!</p>
</div>
</form>
以及相关的指令...
app.directive('active', ['$parse', function ($parse) {
var tid;
return {
restrict: 'A',
require: '?ngModel',
scope:
{
isActive: "=",
ngModel: "="
},
link: function (scope, elem, attrs, ctrl) {
elem.bind('blur', function()
{
scope.isActive = false;
elem.removeClass("ng-active");
});
var timeout = attrs.active || 2000;
ctrl.$parsers.unshift(function(value)
{
scope.isActive = true;
console.log("adding class");
elem.addClass("ng-active");
if (tid) clearTimeout(tid);
tid = setTimeout(function()
{
console.log("timeout elapsed, removing class");
scope.$apply(function(){
scope.isActive = false;
});
elem.removeClass("ng-active")
}, timeout);
return value;
})
}
};
}]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function TestCtrl($scope)
{
$scope.testName = "Validation Test";
$scope.user = {
email: 'test@foo.com'
};
$scope.state = {
active: false
};
}
这里是a fiddle of this code running
基本上,它可以工作,但我不喜欢我必须为每个输入字段传递一个外部属性,我不喜欢验证检查的不对称性。有没有更好的方法来做到这一点?
【问题讨论】:
标签: javascript angularjs angularjs-directive angularjs-scope