指令中需要父 FormController 的 Angular (scope?) 问题
Angular (scope?) issues in a Directive that requires the parent FormController
这是一个
人为的例子,但它演示了我遇到的问题。
我有一个表单,其中包含使用指令生成的输入。代码类似于以下内容。小提琴来了 http://jsfiddle.net/technicolorenvy/CFynn/2/
视图
<div ng-controller="AppController">
<form name="myForm">
<input name="myInput" id="myInput" ng-model="myInputModel" ng-pattern="/'d+/" my-directive required/>
<button type="submit" ng-click="submitForm()">Submit</button>
</form>
</div>
控制器
app.controller('AppController', function ($scope) {
$scope.submitForm = function () {
console.log('form controller inside AppController submitForm()');
console.log(angular.copy($scope.myForm));
console.log('is the form valid? ' + $scope.myForm.$valid);
console.log(' ');
};
});
命令
app.directive('myDirective', function () {
return {
template: '<div><input/></div>',
replace: true,
restrict: 'A',
require: '^form',
compile: function (element, attrs) {
// some setup here
// move the id and ng-model down onto the enclosed input
element.removeAttr('id').removeAttr('ng-model').removeAttr('name');
element.find('input').attr('id', attrs.id).attr('ng-model', attrs.ngModel).attr('name', attrs.name);
var inputName = attrs.name,
$input = element.find('input');
if (attrs.required) {
element.removeAttr('required');
$input.attr('required', true);
}
if (attrs.ngPattern) {
element.removeAttr('ng-pattern');
$input.attr('ng-pattern', attrs.ngPattern);
}
return {
pre: function (scope, element, attrs, formCtrl) {
var patternErrs,
fakeNum = 1234;
$input.on('change', function () {
patternErrs = formCtrl.$error.pattern;
if (patternErrs && patternErrs.length > 0) {
angular.forEach(patternErrs, function (err) {
if (err.$name === inputName) {
$input.val(fakeNum);
formCtrl[inputName].$setViewValue(fakeNum);
formCtrl[inputName].$setValidity('pattern', true);
}
});
}
console.log('formCtrl inside directive');
console.log(angular.copy(formCtrl));
console.log('is the form valid? ' + formCtrl.$valid);
console.log(' ');
});
}
};
}
}
});
在指令中,我在"生成的"输入上有一个onChange事件,该事件检查与此输入名称匹配的模式错误,然后如果有,则使用假值强制数据是我们需要的,使用setViewValue
,然后使用setValidity
设置有效性。
这行得通...有点。问题是,在第一次提交时,表单始终无效。您必须单击"提交"两次才能将表单视为有效。(步骤如下)
- 在输入中输入一个字符串(例如"abcd")
- 输入模式验证失败,然后获得有效值 (1234)
- 指令"myDirective"处理此+设置输入的值和有效性
- 但是,在第一个sumbit上,表单无效
- 在第二次提交时,无需更改输入,表单有效
那么我如何在不加强表单有效性的情况下使表单在第一次提交时有效(阅读,我不想手动将表单设置为有效)。这感觉像是一个范围界定问题,但如果是,我不太确定如何补救它。
谢谢!
完成
更改范围后,您需要在更改事件中调用scope.$apply()
。
可是。。我不确定你在这里想做什么。
似乎您可能正在尝试以复杂的方式解决一个简单的问题。很明显,代码不是很可测试。也许正在执行的某些操作实际上是可以封装在控制器中的"业务逻辑"?
这里的确切目标是什么?
你的 $input.on('change') 中的代码永远不会被消化......也就是说,Angular 从来不知道在您的更改事件之后运行其所有监视和内部程序。因此,它会在第一次摘要期间运行它,这是在您第一次运行提交时发生的。
我认为如果您将该位包装在 $timeout() 中或使用 $scope.$apply(),它将解决问题。
相关文章:
- $scope和$routeParams的角度问题
- AngularJS中存在与$scope变量相关的问题.UI中的值未更改
- 在我的HTML中用ng-init初始化$scope变量时出现问题
- 在web工作者、快速定时器和$scope中遇到AngularJS性能问题$apply()
- 指令中需要父 FormController 的 Angular (scope?) 问题
- Angular Js 中的 Scope 问题
- UI-GRID:访问$scope的问题
- 在 AngularJS 中将对象推送到 $scope.array 与 var x = [ ] 相比时是否存在任何性能问题
- 在`$scope.eventSource`上,属性`className`不't加起来就是问题
- ng show和$scope$应用问题
- Angularjs-在$resource-delete方法的回调中更新$scope的问题(thinkster.io第三章
- 我该如何解决这个Angular $scope问题?
- scope查看对象方法的问题
- AngularJS:$watch未在更改时触发(包含页面的$scope问题)
- Angular $scope和ng-if/ng-show问题.视图中的状态没有改变
- $scope使用承诺的问题
- 用ng重复值设置$scope值的问题是没有更新
- $scope问题.更改未显示在 HTML 视图中
- 在 $scope.result 中附加数据时出现问题
- 从ng视图访问$scope时遇到问题