在input中对ng模型进行过滤
我有一个文本input,我不想让用户使用空格,input的东西都会变成小写。
我知道我不允许在ng-model上使用filter。
ng-model='tags | lowercase | no_spaces'
我看着创build我自己的指令,但添加函数到$parsers
和$formatters
没有更新input,只有其他ng-model
元素。
我怎样才能改变我正在input的input?
我基本上试图创build“标签”function,就像在StackOverflow这里的工作。
我build议观看模型的价值和更新chage: http ://plnkr.co/edit/Mb0uRyIIv1eK8nTg3Qng? p= preview
唯一有趣的问题是空格:在AngularJS 1.0.3 ng模型的input自动修剪string,所以它不检测模型已经改变,如果你在结束时或在开始时添加空格(所以空格不会自动删除我的码)。 但在1.1.1中有'ng-trim'指令,允许禁用这个function( 提交 )。 所以我决定使用1.1.1来实现你在你的问题中描述的确切function。
我相信AngularJSinput和ngModel
direcive的意图是无效的input不应该在模型中结束 。 该模型应该始终有效。 拥有无效模型的问题是我们可能会让观察者根据无效模型进行(不恰当)动作。
正如我所看到的,这里的正确解决scheme是插入$parsers
pipe道,并确保无效的input不会进入模型。 我不确定你是怎么试着用$parsers
来处理事情的,但是这里有一个简单的指令来解决你的问题(或者至less是我对这个问题的理解):
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提出的解决scheme中,我们需要使用ng-trim
指令,如果我们想在input的开始/结束处禁止空格。
这种方法的优点是双重的:
- 无效的值不传播到模型
- 使用指令很容易将这个自定义validation添加到任何input,而无需一遍又一遍地重复观察者
解决这个问题的办法可能是在控制器端应用filter:
$scope.tags = $filter('lowercase')($scope.tags);
不要忘记将$filter
声明为依赖项。
我有一个类似的问题,并使用
ng-change="handler(objectInScope)"
在我的处理程序中,我调用objectInScope的方法来正确地修改自己(粗略的input)。 在控制器中,我已经启动了某个地方
$scope.objectInScope = myObject;
我知道这不使用任何奇特的filter或观察者…但它很简单,很好。 唯一不利的是,objectInScope是在调用处理程序时发送的。
使用添加到$ formatters和$ parsers集合的指令来确保转换在两个方向上执行。
有关更多详细信息,请参阅其他答案 ,包括jsfiddle的链接。
你可以试试这个
$scope.$watch('tags ',function(){ $scope.tags = $filter('lowercase')($scope.tags); });
如果您正在进行复杂的asynchronousinputvalidation,则可能需要将自定义类的一部分抽象ng-model
一个级别,并使用自己的validation方法。
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>
码
(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) }) }; })();