ngModelController $parser рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреБрдЫ рдирд┐рдпрдореЛрдВ рдХреЗ рдЕрдиреБрд░реВрдк рдЗрдирдкреБрдЯ рдорд╛рдиреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╕рдордп, $parser рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмрд╛рд░-рдмрд╛рд░ "рдЕрдорд╛рдиреНрдп" рдХреАрд╕реНрдЯреНрд░реЛрдХреНрд╕ рдкрд░ рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдЕрдорд╛рдиреНрдп рд╡рд░реНрдгреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдирд┐рд░реНрджреЗрд╢ рд╕рднреА рдЧреИрд░-рдЕрдВрдХреАрдп рд╡рд░реНрдгреЛрдВ рдХреЛ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред рдпрд╣ рдЬреНрдпрд╛рджрд╛рддрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдПрдХ рд╣реА рдЧреИрд░-рдЕрдВрдХреАрдп рд╡рд░реНрдг рдХреЛ рд▓рдЧрд╛рддрд╛рд░ рджреЛ рдмрд╛рд░ рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╣реИрдВ (рдЬреИрд╕реЗ 'xx'), рддреЛ рдЗрдирдкреБрдЯ рдореЗрдВ рдПрдХ 'x' рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ред рдпрджрд┐ рдЖрдк рддреАрд╕рд░реА рдмрд╛рд░ 'x' рдЯрд╛рдЗрдк рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ 'x' рдХреЛ рд╣рдЯрд╛ рджреЗрдЧрд╛ред
рдореИрдВрдиреЗ рдПрдХ рдЕрд╕рдлрд▓ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓рд╛ рднреА рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рд╣реИред
рд╕рднреА рдХреЛрдб http://codepen.io/visnup/pen/YXgLVq?editors=101 рдкрд░ рдЪрд▓ рд░рд╣реЗ рд╣реИрдВ
рдирд┐рд░реНрджреЗрд╢рд╛рддреНрдордХ рдЙрдкрдпреЛрдЧ
<div ng-app="digits">
<input ng-model="number" placeholder="digits only" digits-only />
</div>
рдЖрджреЗрд╢
angular
.module('digits', [])
.directive('digitsOnly', function() {
return {
require: 'ngModel',
link: function link(scope, element, attrs, ngModel) {
ngModel.$parsers.push(function(value) {
var numbers = value.replace(/\D/g, '');
element.val(numbers);
return numbers;
});
}
};
});
рдЕрд╕рдлрд▓ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓рд╛
describe('digits', function() {
beforeEach(angular.mock.module('digits'));
let scope, input;
beforeEach(inject(function($compile, $rootScope) {
scope = $rootScope;
input = $compile('<input ng-model="number" digits-only />')(scope);
}));
// works
it('should block non-digits', function() {
input.val('111x');
input.triggerHandler('input');
expect(input.val()).to.equal('111');
});
// doesn't work
it('should not flash incorrect input', function() {
input.val('111x');
input.triggerHandler('input');
input.val('111x');
input.triggerHandler('input');
expect(input.val()).to.equal('111');
});
});
рдЗрд╕реЗ рдкрд╣рд▓реЗ #10700 рдореЗрдВ рд▓рд╛рдпрд╛ рдЬрд╛ рдЪреБрдХрд╛ рд╣реИред
$parsers
$viewValue
рдХреЛ $modelValue
рд░реВрдк рдореЗрдВ "рд╕рд╣реЗрдЬрдиреЗ" рд╕реЗ рдкрд╣рд▓реЗ рдмрджрд▓рдиреЗ (рдХреА рдПрдХ рдкреНрд░рддрд┐) рдХреЗ рд▓рд┐рдП рд╣реИ (рдФрд░ рдпрд╣реА рдЖрдкрдХрд╛ рдЙрджрд╛рд╣рд░рдг рдХрд░ рд░рд╣рд╛ рд╣реИ)ред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ $viewValue
рдХреЛ рдирд╣реАрдВ рдмрджрд▓ рд░рд╣рд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рддрддреНрд╡ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддрд╛ рд╣реИ), рдЬрд┐рд╕рд╕реЗ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реЛрддрд╛ рд╣реИред
рдпрд╣ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдмреЗрд╣рддрд░ рд╕рдЪрд┐рддреНрд░ рд╣реИ:
$modelValue
: рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд$viewValue
: 1element.val()
: 1$modelValue
: 1$viewValue
: 1element.val()
: 1$modelValue
: 1$viewValue
: 1xelement.val()
: 1x$modelValue
: 1$viewValue
: 1x (рдкрд╛рд░реНрд╕рд░ рдПрдлрдПрди рд╕реЗ рдХрднреА рдЕрдкрдбреЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛)element.val()
: 1 (рдкрд╛рд░реНрд╕рд░ рдПрдлрдПрди рд╕реЗ рдЕрджреНрдпрддрди)$modelValue
: 1$viewValue
: 1x (рдХреЛрдИ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рдкрд╛рдпрд╛ рдЧрдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдкрд┐рдЫрд▓рд╛ $viewValue
рднреА 1x
)element.val()
: 1x$viewValue
рдореЗрдВ рдХреЛрдИ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рдкрд╛рдпрд╛ рдЧрдпрд╛) !!!$modelValue
: 1$viewValue
: 1xelement.val()
: 1x$modelValue
: 1$viewValue
: 1xxelement.val()
: 1xx$modelValue
: 1$viewValue
: 1xxelement.val()
: 1рдЗрд╕реЗ рдареАрдХ рд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рдХрдИ "рдХреЛрдгреАрдп" рддрд░реАрдХреЗ рд╣реИрдВ, рдЬреИрд╕реЗ:
ngModel.$parsers.push(function (value) {
var numbers = value.replace(/\D/g, '');
if (numbers !== value) {
ngModel.$setViewValue(numbers); // Update the `$viewValue`
ngModel.$render(); // Update the element's displayed value
}
return numbers;
});
рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдкреЗрди
рдореИрдВ рдЗрд╕реЗ рдмрдВрдж рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╕рдм рдХреБрдЫ рдЙрдореНрдореАрдж рдХреЗ рдореБрддрд╛рдмрд┐рдХ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред
@visnup , рдЕрдЧрд░ рдХреБрдЫ рднреА рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рддреЛ рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВред
рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдХрд┐рд╕реА рднреА рд╕рдордп рджреЛрд╣рд░рд╛рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХреАрд╕реНрдЯреНрд░реЛрдХ рдХреЗ рд╕рд╛рде рд╣реЛрддреА рд╣реИ рдЬрдм рдирдпрд╛ $viewValue рдкреНрд░рддрд┐рдмрджреНрдз рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред $parsers рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ $setViewValue рдХреЗ рд╕реБрдЭрд╛рдП рдЧрдП рдЙрдкрдпреЛрдЧ рдХреЛ рдХрднреА-рдХрднреА рдХреБрдЫ рдлрд╝реЛрд░рдо рдореЗрдВ рд╕реАрдзреЗ $viewValue рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдХреЗ рд╕рд╛рде рдЯрд╛рд▓рд╛ рдЬрд╛рддрд╛ рд╣реИред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рднреА рдХрд╛рдо рдХрд░реЗрдВрдЧреЗ:
ngModel.$viewValue = numbers; // Update the '$viewValue'
ngModel.$commitViewValue(); //update $$lastCommittedViewValue
ngModel.$render(); // Update the element's displayed value
рдпрджрд┐ рдЖрдк рдХрд┐рд╕реА рднреА рд░рд┐рдХрд░реНрд╕рди рдиреБрдХрд╕рд╛рди рд╕реЗ рдмрдЪрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ $$lastCommittedViewValue рдХреЛ рд╕реАрдзреЗ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рдЖрдкрдХреЛ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рдиреЗ рдореЗрдВ рдХреЛрдИ рдЖрдкрддреНрддрд┐ рдирд╣реАрдВ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдЬрдм рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдореЗрдВ рдЕрдирдВрдд рд░рд┐рдХрд░реНрд╕рди рд╣реЛрддрд╛ рд╣реИ рддреЛ рдореИрдВрдиреЗ рдРрд╕реЗ рдорд╛рдорд▓реЗ рджреЗрдЦреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдЕрдзрд┐рдХрддрдо рдШрдЯрдирд╛рдУрдВ рдХреЗ рдмрд╛рдж рднреА рдХрдВрд╕реЛрд▓ рдХреЛ рдЗрд╕рдХреА рд╕реВрдЪрдирд╛ рдирд╣реАрдВ рджреА рдЬрд╛рддреА рд╣реИред рдкрд░реАрдХреНрд╖рдг рдХреЗ рджреМрд░рд╛рди рдмреНрд░реЗрдХ рдкреНрд╡рд╛рдЗрдВрдЯ рд▓рдЧрд╛рдиреЗ рдФрд░ рдХрд┐рд╕реА рднреА рд░рд┐рдХрд░реНрд╕рди рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдорд┐рдирдЯреЛрдВ рдХрд╛ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред
@gkalpak рдФрд░ @snaptech рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдПрдХ рд╕рд╛рде рдорд┐рд▓рдХрд░ рдПрдХ рд╕реБрдирд╣рд░рд╛ рд╕рдорд╛рдзрд╛рди рдмрдирд╛рддреЗ рд╣реИрдВ :): +1:
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
$parsers
$viewValue
рдХреЛ$modelValue
рд░реВрдк рдореЗрдВ "рд╕рд╣реЗрдЬрдиреЗ" рд╕реЗ рдкрд╣рд▓реЗ рдмрджрд▓рдиреЗ (рдХреА рдПрдХ рдкреНрд░рддрд┐) рдХреЗ рд▓рд┐рдП рд╣реИ (рдФрд░ рдпрд╣реА рдЖрдкрдХрд╛ рдЙрджрд╛рд╣рд░рдг рдХрд░ рд░рд╣рд╛ рд╣реИ)ред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ$viewValue
рдХреЛ рдирд╣реАрдВ рдмрджрд▓ рд░рд╣рд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рддрддреНрд╡ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддрд╛ рд╣реИ), рдЬрд┐рд╕рд╕реЗ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рд╣реЛрддрд╛ рд╣реИредрдпрд╣ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдмреЗрд╣рддрд░ рд╕рдЪрд┐рддреНрд░ рд╣реИ:
$modelValue
: рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд$viewValue
: 1element.val()
: 1$modelValue
: 1$viewValue
: 1element.val()
: 1$modelValue
: 1$viewValue
: 1xelement.val()
: 1x$modelValue
: 1$viewValue
: 1x (рдкрд╛рд░реНрд╕рд░ рдПрдлрдПрди рд╕реЗ рдХрднреА рдЕрдкрдбреЗрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛)element.val()
: 1 (рдкрд╛рд░реНрд╕рд░ рдПрдлрдПрди рд╕реЗ рдЕрджреНрдпрддрди)$modelValue
: 1$viewValue
: 1x (рдХреЛрдИ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рдкрд╛рдпрд╛ рдЧрдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдкрд┐рдЫрд▓рд╛$viewValue
рднреА1x
)element.val()
: 1x$viewValue
рдореЗрдВ рдХреЛрдИ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рдкрд╛рдпрд╛ рдЧрдпрд╛) !!!$modelValue
: 1$viewValue
: 1xelement.val()
: 1x$modelValue
: 1$viewValue
: 1xxelement.val()
: 1xx$modelValue
: 1$viewValue
: 1xxelement.val()
: 1рдЗрд╕реЗ рдареАрдХ рд╕реЗ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рдХрдИ "рдХреЛрдгреАрдп" рддрд░реАрдХреЗ рд╣реИрдВ, рдЬреИрд╕реЗ:
рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдкреЗрди
рдореИрдВ рдЗрд╕реЗ рдмрдВрдж рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╕рдм рдХреБрдЫ рдЙрдореНрдореАрдж рдХреЗ рдореБрддрд╛рдмрд┐рдХ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИред
@visnup , рдЕрдЧрд░ рдХреБрдЫ рднреА рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ рддреЛ рдкреНрд░рд╢реНрдиреЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВред