使用 ng-model 绑定时保留自定义对象类型
Preserving Custom Object Types When Binding Using ng-model
我有一系列扩展基本数组的自定义 javascript 对象。这些对象由数据工厂接收和处理以供主窗体控制器使用。
当绑定到任何输入类型(复选框、单选框、select)时,初始绑定在加载时很好,数据显示并且工作正常。但是,在我更新视图中的值的那一刻,自定义对象类型被覆盖并替换为基本数组。
将数据发送回数据工厂时,我需要知道它是什么类型(有几种),以便确定如何为 SharePoint 列表设置格式。有什么方法可以保留我的对象类型并仍然允许双向绑定吗?
当一个输入通过 ngModel 更新模型时,它通常会用一个覆盖模型初始值的值更新它,并且可能是另一种类型。
有时您可以选择具有内置属性的 return 值,例如复选框或 ng-options 的 ng-true-value 和 ng-false-value "label for value in array"。
如果您不能这样做或需要更可重用的解决方案,您可以使用 ngModel 格式化程序和解析器。
一些背景 - ngModel 实际上包含两个值:
- $modelValue - 范围 属性 在 ngModel 中使用的实际数据
表达式成立 - 例如在
ng-model="variable"
- $modelValue 将是
一个来自变量。
- $viewValue - 输入控件中使用的值 - 例如,用户看到的文本框中的文本。
通常 $modelValue 和 $viewValue 是相同的,但我们可以选择使用 $formatters 和 $parsers 管道更改它们。
$formatters 是我们可以将函数推送到其中的管道。当$modelValue 变化时(即binded prop 变化),数据将被pipeline 中的函数转换,结果为$viewValue.
$parsers 是相反的管道。每当视图值发生变化时,例如 - 有人将文本输入到输入中,$viewValue 就会使用 $parsers 管道转换为模型值。
底线 - 您可以将自定义对象($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
};
}])
管道指令:
.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>
我有一系列扩展基本数组的自定义 javascript 对象。这些对象由数据工厂接收和处理以供主窗体控制器使用。
当绑定到任何输入类型(复选框、单选框、select)时,初始绑定在加载时很好,数据显示并且工作正常。但是,在我更新视图中的值的那一刻,自定义对象类型被覆盖并替换为基本数组。
将数据发送回数据工厂时,我需要知道它是什么类型(有几种),以便确定如何为 SharePoint 列表设置格式。有什么方法可以保留我的对象类型并仍然允许双向绑定吗?
当一个输入通过 ngModel 更新模型时,它通常会用一个覆盖模型初始值的值更新它,并且可能是另一种类型。
有时您可以选择具有内置属性的 return 值,例如复选框或 ng-options 的 ng-true-value 和 ng-false-value "label for value in array"。
如果您不能这样做或需要更可重用的解决方案,您可以使用 ngModel 格式化程序和解析器。
一些背景 - ngModel 实际上包含两个值:
- $modelValue - 范围 属性 在 ngModel 中使用的实际数据
表达式成立 - 例如在
ng-model="variable"
- $modelValue 将是 一个来自变量。 - $viewValue - 输入控件中使用的值 - 例如,用户看到的文本框中的文本。
通常 $modelValue 和 $viewValue 是相同的,但我们可以选择使用 $formatters 和 $parsers 管道更改它们。
$formatters 是我们可以将函数推送到其中的管道。当$modelValue 变化时(即binded prop 变化),数据将被pipeline 中的函数转换,结果为$viewValue.
$parsers 是相反的管道。每当视图值发生变化时,例如 - 有人将文本输入到输入中,$viewValue 就会使用 $parsers 管道转换为模型值。
底线 - 您可以将自定义对象($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
};
}])
管道指令:
.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>