Сохранение пользовательских типов объектов при связывании с использованием ng-модели
У меня есть ряд пользовательских объектов JavaScript, которые расширяют базовый массив. Эти объекты принимаются и обрабатываются фабрикой данных для использования главным контроллером форм.
При привязке к любому типу ввода (флажок, радио, выберите) начальная привязка в порядке при загрузке, данные отображаются и работают нормально. Однако, как только я обновляю значение в представлении, пользовательский тип объекта переопределяется и заменяется базовым массивом.
При отправке данных обратно на фабрику данных мне нужно будет знать, какой это тип (их несколько), чтобы определить, как отформатировать их для списка SharePoint. Есть ли способ сохранить мой тип объекта и при этом разрешить двустороннюю привязку?
1 ответ
Когда вход обновляет модель через ngModel, он обычно обновляет его значением, которое перезаписывает начальное значение модели, и может быть другого типа.
Иногда вы можете выбрать возвращаемое значение со встроенными атрибутами, такими как ng-true-value и ng-false-value для флажков или ng-options "метка для значения в массиве".
Если вы не можете сделать это или вам нужно более многократно используемое решение, вы можете использовать средства форматирования и анализаторы ngModel.
Некоторый фон - ngModel на самом деле содержит два значения:
- $modelValue - фактические данные, которые содержит свойство области, используемое в выражении ngModel - например, в
ng-model="variable"
- $modelValue будет исходить из переменной. - $ viewValue - значение, используемое в элементе управления вводом - например, текст в текстовом поле, который видит пользователь.
Обычно $modelValue и $ viewValue - это одно и то же, но у нас есть возможность изменить их с помощью конвейеров $ formatters и $ parsers.
$ formatters - это конвейер, в который мы можем передавать функции. При изменении $modelValue (т. Е. Изменяется привязанная опора), данные будут преобразованы функциями в конвейере, и результатом будет $ 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>