在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是插入$parserspipe道,并确保无效的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) }) }; })();