How prevent angular auto trim for fields?

不羁岁月 提交于 2019-12-10 16:09:33

问题


Is there any way prevent angular from auto trim for fields in the whole application? I know that I can prevent it for specified field using ngTrim directive, but it doesn't look good add this directive to all text fields in the application, is there any way do it for all fields in the angular module? Here is code, if you add add spaces in the begin of input they will not appear in label:

<div ng-app>
  <div ng-controller="TodoCtrl">
      {{field}}
    <input type="text" ng-model="field">
  </div>
</div>

回答1:


You can extend input[text] directive, the code below will automatically change the value of the attribute ngTrim to false:

.directive('input', function($compile){
    // Runs during compile
    return {
      link(scope, iElement, iAttrs) {
        if (iElement.attr('type') === 'text') {
          iAttrs.$set('ngTrim', "false");
        }
      }
    };
});

Reference: https://docs.angularjs.org/api/ng/type/$compile.directive.Attributes

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example - example-text-input-directive</title>
  

  <script src="https://docs.angularjs.org/angular.min.js"></script>
  

  
</head>
<body ng-app="textInputExample">
  <script>
  angular.module('textInputExample', [])
    .controller('ExampleController', ['$scope', function($scope) {
      $scope.example = {
        text: 'guest'
      };
    }])
    .directive('input', function($compile){
    	// Runs during compile
    	return {
    	  link(scope, iElement, iAttrs) {
    	    if (iElement.attr('type') === 'text') {
    	      iAttrs.$set('ngTrim', "false");
    	    }
    	  }
    	};
    });
</script>
<form name="myForm" ng-controller="ExampleController">
  <label>Single word:
    <input type="text" name="input" ng-model="example.text" required>
  </label>
  <div role="alert">
    <span class="error" ng-show="myForm.input.$error.required">
      Required!</span>
    <span class="error" ng-show="myForm.input.$error.pattern">
      Single word only!</span>
  </div>
  <tt>text = {{example.text}} - 3</tt><br/>
  <tt>text = {{example.text.length}} - 3</tt><br/>
  <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
  <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
  <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
 </form>
</body>
</html>

EDIT:

How it works

1) You can bind multiple directives to the same html element and they can share the same $scope and $attributes.

2) iAttrs.$set('ngTrim', "false"); is updating the attribute ng-trim. You can't do this using normal dom manipulation because the dom is already compiled (https://docs.angularjs.org/api/ng/service/$compile)

3) Calling iAttrs.$set will trigger updates on all directives, so it will override the original ng-trim attribute value.




回答2:


Another way to extend the input directive (or any directive/service, for that matter) is by using a decorator:

app.config(function($provide) {
  $provide.decorator('inputDirective', function($delegate) {
    var directive = $delegate[0],
        link = directive.link;

    link.post = function(scope, element, attrs) {
      attrs.$set('ngTrim', 'false');
    };

    return $delegate;
  });
});

Working Plunker

I personally prefer this approach because it allows me to execute the directive's original code, if needed. In this particular case that isn't necessary because the input directive has no link function, so you can simply provide your own without worrying about breaking anything.



来源:https://stackoverflow.com/questions/30533568/how-prevent-angular-auto-trim-for-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!