Угловая двусторонняя привязка с подэлементами
Моя проблема с созданием угловой директивы.
Я хочу создать группу флажков только с одной нг-моделью. Это как битовое поле или флаги, т.е. флажки имеют значения от 0, 1, 2, 3 до n, но для ng-модели я просто хочу добавить 2^ значение всех отмеченных флажков. Значения, которые нужно добавить: 1, 2, 4, 8, 16, ...
Интересно, есть ли лучшее, более правильное или более простое решение моей проблемы?
http://plnkr.co/edit/9h7EkEpDohXTniIDHdc5
В примере вы можете изменить значение в текстовом поле, и проверки будут обновлены, но не иначе. Это немного сумасшествие, код работает на моей машине разработчика, но не в Plnkr!
app.directive('ngCheckboxFlags', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrls) {
var flagSum;
var checkboxes = [];
// trigger changes of the ngModel
scope.$watch(attrs.ngModel, function (value) {
flagSum = value;
for (var i = 0, ii = checkboxes.length; i < ii; ++i) {
var checkbox = checkboxes[i];
checkbox.checked = flagSum & (1<<checkbox.value);
}
});
for (var i = 0, inputs = element.find('input[type=checkbox]'), ii = inputs.length; i < ii; ++i)
{
var checkbox = inputs[i];
checkboxes.push(checkbox);
// trigger changes of HTML elements
$(checkbox).bind('change', function () {
flagSum = ctrls.$viewValue ^ (1<<this.value);
console.log(flagSum);
//ERROR: Change not happening, textbox shows old value
scope.$apply(function () {
ctrls.$setViewValue(flagSum);
});
});
}
}
};
});
спасибо заранее кнут
2 ответа
Не связывай ng-model
непосредственно к примитивным типам, используйте вместо этого объект:
$scope.sum = {
ofCheckValues: 3
};
И на HTML:
ng-model="sum.ofCheckValues"
"Всякий раз, когда у вас есть модель нг, где-то там должна быть точка. Если у вас нет точки, вы делаете это неправильно ".
plunker: http://plnkr.co/edit/NRAk3kyP1rdDmYrsz6ZL?p=preview
Нашли более элегантный и короткий путь: http://plnkr.co/edit/9h7EkEpDohXTniIDHdc5
Моя проблема была
- не понял, что link() вызывается для каждого элемента
- поэтому каждый раз, когда создается новая "область" (для каждого элемента)
- Мне просто нужно сохранить ссылку на фактический элемент в моей переменной (теперь она называется checkbox; был массивом в первой версии) для ее обновления при изменении модели (scope.$ Watch)
Мне не нужен "глобальный" flagSum, просто локальный в checkbox-привязке для передачи значения в область. $ Apply
app.directive('ngCheckboxFlags', function () { return { restrict: 'A', require: 'ngModel', link: function (scope, element, attrs, ctrls) { var checkbox = element.find('input[type=checkbox]')[0]; if (typeof checkbox === "undefined") return; // trigger changes of the ngModel scope.$watch(attrs.ngModel, function (value) { checkbox.checked = value & (1<<checkbox.value); }); $(checkbox).bind('change', function () { var flagSum = ctrls.$viewValue ^ (1<<this.value); scope.$apply(function () { ctrls.$setViewValue(flagSum); }); }); } }; });