0

我有一个 AngularJS 指令,它包含一个文本输入,它有自己的模型,该模型通过指令的 ng-model 从控制器范围传递一个值。

看看这支笔(和下面的代码):http ://codepen.io/ericwshea/pen/KwXRyr

问题是有时该模型恰好是空值或未定义值,在这种情况下,我想使用文本输入的 ngModelController 将文本输入中空值的显示格式化为类似于“NULL”的内容。

如果该值是我在格式化程序中匹配的任意字符串,则它可以工作,但如果该值为 null 则不能(我也用未定义的相同结果进行了测试)。

对此有任何见解/解决方法,还是这只是 $formatters 的缺点?

HTML:

<div ng-app="app" class="container">
  <div ng-controller="ctrl" class="col-md-12">
    <form>
      <input-directive ng-model="model"></input-directive>
      <input-directive ng-model="model2"></input-directive>
      <div ng-if="model">Model 1: {{model}}</div>
      <div ng-if="model2">Model 2: {{model2}}</div>
    </form>
  </div>
</div>

JAVASCRIPT:

angular.module('app', [])
  .controller('ctrl', function($scope) {
    $scope.model = null;
    $scope.model2 = 'make this null';
  })

  .directive('inputDirective', function() {
    var template = 
        '<div>'+
          '<div class="input-group">'+
            '<input type="text" class="form-control" ng-model="localModel">'+
            '<span class="input-group-btn">'+
              '<button ng-click="save()" class="btn btn-default" type="button">Save</button>'+
            '</span>'+
          '</div>'+
        '</div>';

    function link (scope, elem, attr) {
      var inputModelCtrl = elem.find('input').controller('ngModel');

      function formatter(val) {
        if (val === 'make this null') {
          return scope.nullValue;
        }
        if (val === null) {
          return scope.nullValue;
        }
        return val;
      }

      scope.nullValue = 'NULL';
      scope.localModel = scope.ngModel;
      scope.save = function() {
        scope.ngModel = scope.localModel;
      }
      inputModelCtrl.$formatters.push(formatter);
    }

    return {
      restrict: 'E', 
      replace: true,
      require: 'ngModel',
      template: template,
      link: link,
      scope: {
        ngModel: '='
      }
    }
  })
;
4

1 回答 1

0

我设法为此找到了解决方法。我在创建指令时初始化值,方法是在 ngModel 上放置一个手表,捕获 null 并将其设置为“NULL”,角度 $formatters 将实际格式化。我将 localModel 的视图值格式化为 ,它可以工作。

为了确保当我将“NULL”从指令发送回控制器范围时模型值是正确的,我在 ngModelController 上使用 $parser 来监视“NULL”并将其转换为 null。

为了让它完整循环,ngModel 指令中的 $watch 使得如果在指令之外将该值设置为 null,则 localModel 将重新初始化为“NULL”并格式化为正确显示。

这可能看起来很荒谬,但实际的现实世界指令是一个自定义选择菜单,正如您可以想象的那样,它需要这个功能。

您可以在此处查看更改:http: //codepen.io/ericwshea/pen/KwXRyr

angular.module('app', [])
  .controller('ctrl', function($scope) {
    $scope.model = null;
    $scope.getModel = function() {
      return $scope.model === null ? 'null' : $scope.model;
    }
    $scope.setToNull = function() {
      $scope.model = null;
    }
  })

  .directive('inputDirective', function() {
    var template = 
        '<div>'+
          '<div class="input-group">'+
            '<input type="text" class="form-control" ng-model="localModel">'+
            '<span class="input-group-btn">'+
              '<button ng-click="save()" class="btn btn-default" type="button">Save</button>'+
            '</span>'+
          '</div>'+
        '</div>';

    function link (scope, elem, attr, ngModelCtrl) {
      var inputModelCtrl = elem.find('input').controller('ngModel');
      var nullDisplay = '<NULL>';

      function ngModelParser(val) {
        if (val === 'NULL') return null;
        return val;
      }

      function localModelFormatter(val) {
        if (val === 'NULL') return nullDisplay;
        return val;
      }

      scope.save = function() {
        ngModelCtrl.$setViewValue(scope.localModel);
        console.log(ngModelCtrl.$modelValue);
      }

      scope.$watch('ngModel', function(val) {
        if (val === null) val = 'NULL';
        scope.localModel = val;
      })

      inputModelCtrl.$formatters.push(localModelFormatter);
      ngModelCtrl.$parsers.push(ngModelParser);
    }

    return {
      restrict: 'E', 
      replace: true,
      require: 'ngModel',
      template: template,
      link: link,
      scope: {
        ngModel: '='
      }
    }
  })
;

我希望这可以帮助遇到类似问题的任何人,即使这种情况相当具体(具体到我必须自己回答!)

于 2015-02-19T20:20:29.087 回答