Так что мой случай использования:AngularJs - Пересвязывание нг-модель
cols = [{field="product.productId"},{field="product.productPrice"}];
data = {products:[{product:{productId:1,productPrice:10}, {product:{productId:2, productPrice:15}}]}
То, что я хотел бы сделать, это:
<div ng-repeat="product in data.products">
<div ng-repeat="col in cols">
<input type="text" ng-model="product[col.field]"></>
</div>
</div>
Теперь, если col.field был просто «someField», а не «some.deep.field», это сработает. Поскольку поле имеет много элементов, правильным способом сделать ng-модель будет «product [some] [deep] [field]», если я не хочу быть общим и разрешать изменение моих данных и столбцов. Я пробовал этот подход, и он работал для не-общего использования.
То, что я пытался сделать это родовое:
Пересобираем мой элемент 'ввода'. Это создает идеальный HTML E.G, он имеет ng-model = "product ['some'] ['deep'] ['field']" на нем, но никоим образом не связано полем. Возможно, я компилирую с неправильной областью? Я попытался добавитьAttribute ng-init = "hello = 'Hey'" ng-model = "hello" в этот момент, и он работал и правильно привязан ... поэтому я чувствую, что у меня отсутствует что-то относительно области действия здесь.
compile: function (templateElement) { templateElement[0].removeAttribute('recursive-model'); templateElement[0].removeAttribute('recursive-model-accessor'); return { pre: function (scope, element, attrs) { function convertDotToMultiBracketNotation(dotNote) { var ret = []; var arrayOfDots = dotNote.split('.'); for (i = 0; i < arrayOfDots.length; i++) { ret.push("['" + arrayOfDots[i] + "']"); } return ret.join(''); } if (attrs.recursiveModel && attrs.recursiveModelAccessor) { scope[scope.recursiveModel] = scope.ngModel; element[0].setAttribute('ng-model', scope.recursiveModel + convertDotToMultiBracketNotation(scope.recursiveModelAccessor)); var res = $compile(element[0])(scope); console.info('new compiled element:', res); return res; } } } }
Мессинга с NgModelController для форматирования и синтаксического анализа. В этом случае я поместил весь объект «строка» в ng-модель, а затем использовал formatter/parser, чтобы испортить только поле 1, которое меня интересовало. Это работает, пока вы не очистите поле. В этот момент, похоже, полностью уничтожается modelCtrl. $ ModelValue. Других слов - мой console.log говорит:
Настройка поле для VAL 'Текст' на строке [объект]
Настройка поле ВАЛ 'Текс' на строке [объект]
Настройка поля для валь 'Te' на строке [объект]
Установка поле VAL 'T' на строке [объект]
Окружение поле Вала «» на строке [объект]
Настройки поле для VAL «A» на строке неопределенной
link: function (scope, element, attrs, ctrls) {
if(ctrls[2] && scope.recursiveModelAccessor){
var modelCtrl = ctrls[2];
modelCtrl.$formatters.push(function (inputValue) {
function getValue(object, string){
var explodedString = string.split('.');
for (i = 0, l = explodedString.length; i < l; i++) {
object = object[explodedString[i]];
}
return object;
};
function getValueRecursive (row, field) {
if (field instanceof Array) {
var ret = [];
for (var i = 0; i < col.field.length; i++) {
ret.push(getValue(row, field[i]));
}
return ret.join('/');
} else {
return getValue(row, field);
}
};
return getValueRecursive(modelCtrl.$modelValue, scope.recursiveModelAccessor);
});
modelCtrl.$parsers.push(function (inputValue) {
function setValueRecursive (row, field, newValue) {
if (field instanceof Array) {
var firstField = field.shift();
if(field.length==1){
field = field[0];
}
setValueRecursive(row[firstField], field, newValue);
} else {
console.log("Setting "+field+" to val:"+newValue+" on row:"+row);
row[field]=newValue;
}
};
setValueRecursive(modelCtrl.$modelValue, scope.recursiveModelAccessor.split('.'), modelCtrl.$viewValue);
return modelCtrl.$modelValue;
});