Угловая двусторонняя привязка с подэлементами

Моя проблема с созданием угловой директивы.

Я хочу создать группу флажков только с одной нг-моделью. Это как битовое поле или флаги, т.е. флажки имеют значения от 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);
                });
            });
        }
      };
    });
    
Другие вопросы по тегам