AngularJS를 사용한 양식의 동적 유효성 검사 및 이름
이 양식이 있습니다 : http://jsfiddle.net/dfJeN/
보시다시피 입력의 이름 값은 정적으로 설정됩니다.
name="username"
, 양식 유효성 검사가 제대로 작동합니다 (입력에서 무언가를 추가하고 모든 텍스트를 제거하면 텍스트가 표시되어야 함).
그런 다음 이름 값을 동적으로 설정하려고합니다. http://jsfiddle.net/jNWB8/
name="{input.name}"
그런 다음 이것을 내 유효성 검사에 적용합니다.
login.{{input.name}}.$error.required
(이 패턴은 ng-repeat에서 사용됩니다) 내 양식 유효성 검사가 손상되었습니다. 그것은 내 브라우저에서 올바르게 해석됩니다 (내가 login.username. $ error.required를 본 요소를 검사하면).
어떤 아이디어?
편집 : 콘솔에 범위를 기록한 후
{{input.name}}
식은 보간되지 않습니다. 내 양식은 {{input.name}} 속성이지만 사용자 이름은 없습니다.
업데이트 : 1.3.0-rc.3 name = "{{input.name}}"이 예상대로 작동합니다. # 1404를 참조하십시오
그런 식으로하려는 것을 할 수 없습니다.
ng-repeat와 같이 양식에 요소를 동적으로 추가해야한다고 가정하면 중첩 된 ng-form 을 사용하여 해당 개별 항목의 유효성을 검사해야합니다.
<form name="outerForm">
<div ng-repeat="item in items">
<ng-form name="innerForm">
<input type="text" name="foo" ng-model="item.foo" />
<span ng-show="innerForm.foo.$error.required">required</span>
</ng-form>
</div>
<input type="submit" ng-disabled="outerForm.$invalid" />
</form>
안타깝게도 Angular의 잘 문서화 된 기능이 아닙니다.
중첩 된 ngForm을 사용하면 HTML 템플릿 내에서 특정 InputController에 액세스 할 수 있습니다. 그러나 다른 컨트롤러에서 액세스하려는 경우 도움이되지 않습니다.
예 :
<script>
function OuterController($scope) {
$scope.inputName = 'dynamicName';
$scope.doStuff = function() {
console.log($scope.formName.dynamicName); // undefined
console.log($scope.formName.staticName); // InputController
}
}
</script>
<div controller='OuterController'>
<form name='myForm'>
<input name='{{ inputName }}' />
<input name='staticName' />
</form>
<a ng-click='doStuff()'>Click</a>
</div>
이 지시문을 사용하여 문제를 해결합니다.
angular.module('test').directive('dynamicName', function($compile, $parse) {
return {
restrict: 'A',
terminal: true,
priority: 100000,
link: function(scope, elem) {
var name = $parse(elem.attr('dynamic-name'))(scope);
// $interpolate() will support things like 'skill'+skill.id where parse will not
elem.removeAttr('dynamic-name');
elem.attr('name', name);
$compile(elem)(scope);
}
};
});
이제 필요한 모든 곳에 'name'속성 대신 'dynamic-name'속성 만 동적 이름을 사용합니다.
예 :
<script>
function OuterController($scope) {
$scope.inputName = 'dynamicName';
$scope.doStuff = function() {
console.log($scope.formName.dynamicName); // InputController
console.log($scope.formName.staticName); // InputController
}
}
</script>
<div controller='OuterController'>
<form name='myForm'>
<input dynamic-name='inputName' />
<input name='staticName' />
</form>
<a ng-click='doStuff()'>Click</a>
</div>
The problem should be fixed in AngularJS 1.3, according to this discussion on Github.
Meanwhile, here's a temporary solution created by @caitp and @Thinkscape:
// Workaround for bug #1404
// https://github.com/angular/angular.js/issues/1404
// Source: http://plnkr.co/edit/hSMzWC?p=preview
app.config(['$provide', function($provide) {
$provide.decorator('ngModelDirective', function($delegate) {
var ngModel = $delegate[0], controller = ngModel.controller;
ngModel.controller = ['$scope', '$element', '$attrs', '$injector', function(scope, element, attrs, $injector) {
var $interpolate = $injector.get('$interpolate');
attrs.$set('name', $interpolate(attrs.name || '')(scope));
$injector.invoke(controller, this, {
'$scope': scope,
'$element': element,
'$attrs': attrs
});
}];
return $delegate;
});
$provide.decorator('formDirective', function($delegate) {
var form = $delegate[0], controller = form.controller;
form.controller = ['$scope', '$element', '$attrs', '$injector', function(scope, element, attrs, $injector) {
var $interpolate = $injector.get('$interpolate');
attrs.$set('name', $interpolate(attrs.name || attrs.ngForm || '')(scope));
$injector.invoke(controller, this, {
'$scope': scope,
'$element': element,
'$attrs': attrs
});
}];
return $delegate;
});
}]);
Demo on JSFiddle.
Nice one by @EnISeeK.... but i got it to be more elegant and less obtrusive to other directives:
.directive("dynamicName",[function(){
return {
restrict:"A",
require: ['ngModel', '^form'],
link:function(scope,element,attrs,ctrls){
ctrls[0].$name = scope.$eval(attrs.dynamicName) || attrs.dynamicName;
ctrls[1].$addControl(ctrls[0]);
}
};
}])
Just a little improvement over EnlSeek solution
angular.module('test').directive('dynamicName', ["$parse", function($parse) {
return {
restrict: 'A',
priority: 10000,
controller : ["$scope", "$element", "$attrs",
function($scope, $element, $attrs){
var name = $parse($attrs.dynamicName)($scope);
delete($attrs['dynamicName']);
$element.removeAttr('data-dynamic-name');
$element.removeAttr('dynamic-name');
$attrs.$set("name", name);
}]
};
}]);
Here is a plunker trial. Here is detailed explantion
I expand the @caitp and @Thinkscape solution a bit, to allow dynamically created nested ng-forms, like this:
<div ng-controller="ctrl">
<ng-form name="form">
<input type="text" ng-model="static" name="static"/>
<div ng-repeat="df in dynamicForms">
<ng-form name="form{{df.id}}">
<input type="text" ng-model="df.sub" name="sub"/>
<div>Dirty: <span ng-bind="form{{df.id}}.$dirty"></span></div>
</ng-form>
</div>
<div><button ng-click="consoleLog()">Console Log</button></div>
<div>Dirty: <span ng-bind="form.$dirty"></span></div>
</ng-form>
</div>
Here is my demo on JSFiddle.
I used Ben Lesh's solution and it works well for me. But one problem I faced was that when I added an inner form using ng-form
, all of the form states e.g. form.$valid, form.$error
etc became undefined if I was using the ng-submit
directive.
So if I had this for example:
<form novalidate ng-submit="saveRecord()" name="outerForm">
<!--parts of the outer form-->
<ng-form name="inner-form">
<input name="someInput">
</ng-form>
<button type="submit">Submit</button>
</form>
And in the my controller:
$scope.saveRecord = function() {
outerForm.$valid // this is undefined
}
So I had to go back to using a regular click event for submitting the form in which case it's necessary to pass the form object:
<form novalidate name="outerForm"> <!--remove the ng-submit directive-->
<!--parts of the outer form-->
<ng-form name="inner-form">
<input name="someInput">
</ng-form>
<button type="submit" ng-click="saveRecord(outerForm)">Submit</button>
</form>
And the revised controller method:
$scope.saveRecord = function(outerForm) {
outerForm.$valid // this works
}
I'm not quite sure why this is but hopefully it helps someone.
This issue has been fixed in Angular 1.3+ This is the correct syntax for what you are trying to do:
login[input.name].$invalid
if we set dynamic name for a input like the below
<input name="{{dynamicInputName}}" />
then we have use set validation for dynamic name like the below code.
<div ng-messages="login.dynamicInputName.$error">
<div ng-message="required">
</div>
</div>
참고URL : https://stackoverflow.com/questions/14378401/dynamic-validation-and-name-in-a-form-with-angularjs
'programing' 카테고리의 다른 글
스레드 경합이란 무엇입니까? (0) | 2020.08.21 |
---|---|
C / C ++ 줄 번호 (0) | 2020.08.21 |
테이블 정의를 표시하는 T-SQL 쿼리? (0) | 2020.08.21 |
현재 실행 가능한 파일 이름을 어떻게 찾습니까? (0) | 2020.08.21 |
일부 매개 변수를 전달하여 인 텐트를 시작하는 방법은 무엇입니까? (0) | 2020.08.21 |