使用ng-model绑定时保留自定义对象类型

时间:2015-08-07 17:54:48

标签: javascript angularjs angularjs-ng-model

我有一系列自定义javascript对象,它们扩展了基本数组。这些对象由数据工厂接收和处理,供主表单控制器使用。

enter image description here

当绑定到任何输入类型(复选框,无线电,选择)时,初始绑定在加载时很好,数据显示并正常工作。但是,在更新视图中的值时,自定义对象类型将被覆盖并替换为基本数组。

enter image description here

将数据发送回数据工厂时,我需要知道它的类型(有几种),以确定如何为SharePoint列表格式化数据。有没有办法保留我的对象类型,仍然允许双向绑定?

1 个答案:

答案 0 :(得分:3)

当输入通过ngModel更新模型时,它通常使用覆盖模型初始值的值更新它,并且可能是另一种类型。

有时您可以选择具有内置属性的返回值,例如复选框的ng-true-value和ng-false-value或ng-options“数组中值的标签”。

如果您不能这样做或需要更可重用的解决方案,则可以使用ngModel格式化程序和解析器。

一些背景 - ngModel实际上包含两个值:

  • $ modelValue - 范围属性在ngModel中使用的实际数据 表达式成立 - 例如在ng-model="variable" - $ modelValue中 来自变量的那个。
  • $ viewValue - 输入控件中使用的值 - 例如,用户看到的文本框中的文本。

通常$ modelValue和$ viewValue是相同的,但我们可以选择使用$ formatters和$ parsers管道来更改它们。

$ formatters是一个我们可以推送函数的管道。当$ modelValue改变时(即绑定的prop更改),数据将由管道中的函数转换,结果将是$ viewValue。

$ parsers是相反的管道。每当视图值发生变化时,例如某人将某个文本输入到输入中,就会使用$ parsers管道将$ viewValue转换为模型值。

底线 - 您可以将自定义对象($ modelValue)转换为输入控件($ viewValue)中使用的数据,然后使用这两个管道返回。为此,您需要创建一个简单的指令,并将您喜欢的任何变换器(函数)添加到管道(数组)中。例如(plunker - 打开控制台并单击复选框):

自定义原型:

  function CustomObj(value) {
    this.value = !!value ? 'cats' : 'dogs';
  }

  CustomObj.prototype.getValue = function getValue() {
    return this.value;
  };

控制器:

    .controller('ExampleController', ['$scope', function($scope) {

      $scope.checkboxModel = {
        value1: new CustomObj(true) // the model is an instance of CustomObj
      };
    }])

Pipelines指令:

    .directive('preserveCustom', function() {
      var ddo = {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, el, attrs, ngModel) {

          function formatter(modelValue) {
            if(modelValue instanceof CustomObj) {
              return modelValue.getValue() === 'cats';
            }

            return value;
          }

          function parser(viewValue) {
            return new CustomObj(viewValue);
          }

          ngModel.$formatters.push(formatter);
          ngModel.$parsers.push(parser);
        }
      }

      return ddo;
    });

和html:

<input type="checkbox" ng-model="checkboxModel.value1" preserve-custom>