입력에서 ng-model의 필터
텍스트 입력이 있고 사용자가 공백을 사용하지 못하게하고 입력 한 모든 내용이 소문자로 바뀝니다.
예를 들어 ng-model에서 필터를 사용할 수 없다는 것을 알고 있습니다.
ng-model='tags | lowercase | no_spaces'
난 내 자신의 지시를 생성하지만,에 기능을 추가 보았다 $parsers
및 $formatters
입력했다 유일한 요소가 업데이트되지 않았습니다 ng-model
거기에있다.
현재 입력중인 입력을 어떻게 변경합니까?
본질적으로 StackOverflow의 것과 동일한 작동하는 '태그'기능을 만들려고합니다.
모델 값을보고 chage시 업데이트 할 것을 제안합니다 : http://plnkr.co/edit/Mb0uRyIIv1eK8nTg3Qng?p=preview
유일하게 흥미로운 문제는 공백입니다. 입력시 AngularJS 1.0.3 ng-model은 자동으로 문자열을 자르므로 끝이나 시작 부분에 공백을 추가하면 모델이 변경되었음을 감지하지 못합니다 (따라서 공백은 자동으로 제거되지 않습니다) 암호). 그러나 1.1.1에는이 기능을 비활성화 할 수있는 'ng-trim'지시문이 있습니다 ( commit ). 그래서 귀하의 질문에 설명 된 정확한 기능을 달성하기 위해 1.1.1을 사용하기로 결정했습니다.
AngularJS 입력과 그 ngModel
차이 의 의도는 잘못된 입력이 모델에서 끝나지 않아야한다는 것 입니다. 모델은 항상 유효해야합니다. 유효하지 않은 모델을 갖는 문제는 유효하지 않은 모델을 기반으로 해고하고 부적절한 행동을하는 감시자가있을 수 있다는 것입니다.
내가 알다시피, 여기에 올바른 해결책은 $parsers
파이프 라인 에 연결 하고 유효하지 않은 입력이 모델에 적용되지 않도록하는 것입니다. 나는 당신이 어떻게 사물에 접근하려고했는지 또는 정확히 당신에게 효과가 없었던 것을 확신하지 $parsers
못했지만 여기에 문제를 해결하는 간단한 지시문이 있습니다 (또는 적어도 문제에 대한 나의 이해).
app.directive('customValidation', function(){
return {
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
var transformedInput = inputValue.toLowerCase().replace(/ /g, '');
if (transformedInput!=inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});
위 지시어가 선언되면 다음과 같이 사용할 수 있습니다.
<input ng-model="sth" ng-trim="false" custom-validation>
@Valentyn Shybanov가 제안한 솔루션 ng-trim
에서와 같이 입력 시작 / 끝에서 공백을 허용하지 않으려면 지시문 을 사용해야합니다 .
이 방법의 장점은 2 배입니다.
- 잘못된 값이 모델에 전파되지 않습니다
- 지시문을 사용하면 감시자를 반복해서 반복하지 않고도 입력에이 사용자 지정 유효성 검사를 쉽게 추가 할 수 있습니다.
A solution to this problem could be to apply the filters on controller side :
$scope.tags = $filter('lowercase')($scope.tags);
Don't forget to declare $filter
as dependency.
If you are using read only input field, you can use ng-value with filter.
for example:
ng-value="price | number:8"
Use a directive which adds to both the $formatters and $parsers collections to ensure that the transformation is performed in both directions.
See this other answer for more details including a link to jsfiddle.
I had a similar problem and used
ng-change="handler(objectInScope)"
in my handler I call a method of the objectInScope to modify itself correctly (coarse input). In the controller I have initiated somewhere that
$scope.objectInScope = myObject;
I know this doesn't use any fancy filters or watchers... but it's simple and works great. The only down-side to this is that the objectInScope is sent in the call to the handler...
If you are doing complex, async input validation it might be worth it to abstract ng-model
up one level as part of a custom class with its own validation methods.
https://plnkr.co/edit/gUnUjs0qHQwkq2vPZlpO?p=preview
html
<div>
<label for="a">input a</label>
<input
ng-class="{'is-valid': vm.store.a.isValid == true, 'is-invalid': vm.store.a.isValid == false}"
ng-keyup="vm.store.a.validate(['isEmpty'])"
ng-model="vm.store.a.model"
placeholder="{{vm.store.a.isValid === false ? vm.store.a.warning : ''}}"
id="a" />
<label for="b">input b</label>
<input
ng-class="{'is-valid': vm.store.b.isValid == true, 'is-invalid': vm.store.b.isValid == false}"
ng-keyup="vm.store.b.validate(['isEmpty'])"
ng-model="vm.store.b.model"
placeholder="{{vm.store.b.isValid === false ? vm.store.b.warning : ''}}"
id="b" />
</div>
code
(function() {
const _ = window._;
angular
.module('app', [])
.directive('componentLayout', layout)
.controller('Layout', ['Validator', Layout])
.factory('Validator', function() { return Validator; });
/** Layout controller */
function Layout(Validator) {
this.store = {
a: new Validator({title: 'input a'}),
b: new Validator({title: 'input b'})
};
}
/** layout directive */
function layout() {
return {
restrict: 'EA',
templateUrl: 'layout.html',
controller: 'Layout',
controllerAs: 'vm',
bindToController: true
};
}
/** Validator factory */
function Validator(config) {
this.model = null;
this.isValid = null;
this.title = config.title;
}
Validator.prototype.isEmpty = function(checkName) {
return new Promise((resolve, reject) => {
if (/^\s+$/.test(this.model) || this.model.length === 0) {
this.isValid = false;
this.warning = `${this.title} cannot be empty`;
reject(_.merge(this, {test: checkName}));
}
else {
this.isValid = true;
resolve(_.merge(this, {test: checkName}));
}
});
};
/**
* @memberof Validator
* @param {array} checks - array of strings, must match defined Validator class methods
*/
Validator.prototype.validate = function(checks) {
Promise
.all(checks.map(check => this[check](check)))
.then(res => { console.log('pass', res) })
.catch(e => { console.log('fail', e) })
};
})();
You can try this
$scope.$watch('tags ',function(){
$scope.tags = $filter('lowercase')($scope.tags);
});
참고URL : https://stackoverflow.com/questions/14419651/filters-on-ng-model-in-an-input
'IT story' 카테고리의 다른 글
Rspec, Rails : 컨트롤러의 프라이빗 메소드를 테스트하는 방법? (0) | 2020.07.10 |
---|---|
기본적으로 jQuery UI Accordion을 축소 상태로 유지하려면 어떻게합니까? (0) | 2020.07.10 |
WPF에서 모달 대화 상자를 만드는 방법은 무엇입니까? (0) | 2020.07.10 |
Tomcat의 루트에 내 응용 프로그램 배포 (0) | 2020.07.10 |
node.js에서 파일을 어떻게 이동합니까? (0) | 2020.07.10 |