基本上,我想要完成的是在尝试表单提交后将焦点设置为第一个无效元素。此时,我将元素标记为无效,我可以获取元素的$name
,以便知道它是哪一个。
它正在“正常工作”,但正在抛出“$ apply in progress”错误...
所以我一定做错了。)
到目前为止,这是我的代码:
$scope.submit = function () {
if ($scope.formName.$valid) {
// Good job.
}
else
{
var field = null,
firstError = null;
for (field in $scope.formName) {
if (field[0] != '$')
{
if (firstError === null && !$scope.formName[field].$valid) {
firstError = $scope.formName[field].$name;
}
if ($scope.formName[field].$pristine) {
$scope.formName[field].$dirty = true;
}
}
}
formName[firstError].focus();
}
}
我的字段循环基于this solution,我已阅读this question几次。 似乎首选解决方案是创建一个指令,但是为每个单独的表单元素添加一个指令似乎有点矫枉过正。
使用指令是否有更好的方法来解决这个问题?
答案 0 :(得分:2)
指令代码:
app.directive('ngFocus', function ($timeout, $log) {
return {
restrict: 'A',
link: function (scope, elem, attr) {
scope.$on('focusOn', function (e, name) {
// The timeout lets the digest / DOM cycle run before attempting to set focus
$timeout(function () {
if (name === attr.ngFocusId) {
if (attr.ngFocusMethod === "click")
angular.element(elem[0]).click();
else
angular.element(elem[0]).focus();
}
});
})
}
}
});
要在控制器中使用的工厂:
app.factory('focus', function ($rootScope, $timeout) {
return function (name) {
$timeout(function () {
$rootScope.$broadcast('focusOn', name);
}, 0, false);
};
});
样本控制器:
angular.module('test', []).controller('myCtrl', ['focus', function(focus) {
focus('myElement');
}
答案 1 :(得分:0)
建立指令绝对是可行的方法。否则没有干净的方法来选择angularjs中的元素。它不是这样设计的。我建议你在这件事上查看question。
您不必为每个表单元素创建单个指令。对于每个表格都应该足够了。在指令中,您可以使用element.find('input');
。对于焦点本身,我想你需要包含jQuery并使用它的焦点函数。
你可以如何 - 我不建议这样做 - 直接在你的控制器中使用jQuery。通常,角度形式验证会添加类似ng-invalid-required
等类,您可以将其用作选择器。 e.g:
$('input.ng-valid').focus();
答案 2 :(得分:0)
根据hugo的反馈,我设法将指令整合在一起:
.directive( 'mySubmitDirty', function () {
return {
scope: true,
link: function (scope, element, attrs) {
var form = scope[attrs.name];
element.bind('submit', function(event) {
var field = null;
for (field in form) {
if (form[field].hasOwnProperty('$pristine') && form[field].$pristine) {
form[field].$dirty = true;
}
}
var invalid_elements = element.find('.ng-invalid');
if (invalid_elements.length > 0)
{
invalid_elements[0].focus();
}
event.stopPropagation();
event.preventDefault();
});
}
};
})
这种方法需要jquery,因为element.find()
使用类来查找dom中的第一个无效元素。