3

我的问题是创建一个角度指令。

我想用一个 ng-model 创建一组复选框。它就像一个位域或标志,即复选框的值从 0、1、2、3 到 n,但对于 ng-model,我只想添加所有选中复选框的 2^value。然后要添加的值是 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);
                });
            });
        }
    }
};
});

thnx提前knut

4

2 回答 2

5
于 2013-02-28T11:43:19.460 回答
1

找到了一种更优雅、更短的方法: http: //plnkr.co/edit/9h7EkEpDohXTniIDHdc5

我的问题是

  • 没有意识到,每个元素都会调用 link()
  • 因此每次创建一个新的“范围”(对于每个元素)
  • 我只需要在我的变量(现在称为复选框;在第一个版本中是一个数组)中存储对实际元素的引用,以便在模型更改时更新它(scope.$watch)
  • 我不需要“全局”flagSum,只是复选框绑定中的一个 lokal 用于将值传输到 scope.$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);
                });
            });
        }
      };
    });
    
于 2013-03-15T13:17:38.543 回答