简体   繁体   English

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

[英]Preserving Custom Object Types When Binding Using ng-model

I have a series of custom javascript objects which extend the base Array. 我有一系列自定义javascript对象,它们扩展了基本Array。 These objects are received and processed by the data factory for use by the main form controller. 这些对象由数据工厂接收和处理,以供主窗体控制器使用。

在此处输入图片说明

When bound to a any input type (checkbox, radio, select) the initial binding is fine on load, the data shows and works fine. 当绑定到任何输入类型(复选框,单选,选择)时,初始绑定在加载时就可以了,数据显示并可以正常工作。 However, the minute i update the value in the view, the custom object type is overridden and replaced with a base Array. 但是,当我更新视图中的值时,自定义对象类型将被覆盖并替换为基本Array。

在此处输入图片说明

When sending the data back to the data factory, i will need to know what type it is (there are several) in order to determine how to format it for the SharePoint list. 当将数据发送回数据工厂时,我将需要知道它是什么类型(有几种),以确定如何为SharePoint列表设置其格式。 Is there any way to preserve my object type and still allow for two-way binding? 有什么方法可以保留我的对象类型并仍然允许双向绑定?

When an input updates the model via ngModel it usually updates it with a value that overwrites the model's initial value, and may be of another type. 当输入通过ngModel更新模型时,它通常使用覆盖模型初始值的值来更新模型,并且可能是另一种类型。

Sometimes you can choose the return value with built in attributes, such as ng-true-value and ng-false-value for checkboxes or ng-options "label for value in array". 有时,您可以选择带有内置属性的返回值,例如复选框的ng-true-value和ng-false-value或ng-options“数组中的值的标签”。

If you can't do so or need a more reusable solution, you can use ngModel formatters and parsers. 如果您不能这样做或需要更可重用的解决方案,则可以使用ngModel格式化程序和解析器。

Some background - ngModel actually contains two values: 一些背景-ngModel实际上包含两个值:

  • $modelValue - the actual data that the scope property used in the ngModel expression holds - for example in ng-model="variable" - $modelValue will be the one coming from variable. $ modelValue-ngModel表达式中使用的scope属性保存的实际数据-例如在ng-model="variable" -$ modelValue将是来自变量的数据。
  • $viewValue - the value used in the input control - for example, the text in the text box that the user sees. $ viewValue-输入控件中使用的值-例如,用户看到的文本框中的文本。

Usually $modelValue and $viewValue are the same, but we have the option to change them using $formatters and $parsers pipelines. 通常$ modelValue和$ viewValue是相同的,但是我们可以选择使用$ formatters和$ parsers管道来更改它们。

$formatters is a pipeline to which we can push functions. $ formatters是我们可以向其推送功能的管道。 When $modelValue change (ie the binded prop changes), the data will be transformed by the functions in the pipeline, and the result will be $viewValue. 当$ modelValue更改(即,绑定的prop更改)时,数据将通过管道中的函数进行转换,结果将为$ viewValue。

$parsers is the opposite pipeline. $ parsers是相反的管道。 Whenever the view value changes, for example - someone entered text into an input, the $viewValue is converted using the $parsers pipeline into the model value. 例如,每当视图值更改时-有人在输入中输入了文本,就会使用$ parsers管道将$ viewValue转换为模型值。

Bottom line - you can convert your custom object ($modelValue) to the data used in the input control ($viewValue), and then back using these two pipelines. 底线-您可以将自定义对象($ modelValue)转换为输入控件($ viewValue)中使用的数据,然后使用这两个管道返回。 To do so, you create a simple directive, and add whatever transformers (functions) you like to the pipelines (arrays). 为此,您创建一个简单的指令,然后将所需的任何转换器(函数)添加到管道(数组)中。 For Example ( plunker - open the console and click the checkbox): 例如( plunker-打开控制台,然后单击复选框):

Custom prototype: 定制原型:

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

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

Controller: 控制器:

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

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

Pipelines directive: 管道指令:

    .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;
    });

And the html: 和html:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM