Checkbox 带子元素的角度双向绑定

Checkbox 带子元素的角度双向绑定,checkbox,angularjs,model-binding,angularjs-directive,Checkbox,Angularjs,Model Binding,Angularjs Directive,我的问题是创建角度指令 我想用一个ng模型创建一组复选框。它就像一个位域或标志,即复选框的值从0、1、2、3到n,但对于ng模型,我只想在所有复选框中添加2^值。然后要添加的值是1、2、4、8、16、 我想知道是否有更好、更正确或更简单的方法来解决我的问题 在本例中,您可以更改文本框中的值,检查将被更新,但不能以其他方式更新。这有点疯狂,代码在我的开发机器上运行,但不在Plnkr中 app.directive('ngCheckboxFlags', function () { return {

我的问题是创建角度指令

我想用一个ng模型创建一组复选框。它就像一个位域或标志,即复选框的值从0、1、2、3到n,但对于ng模型,我只想在所有复选框中添加2^值。然后要添加的值是1、2、4、8、16、

我想知道是否有更好、更正确或更简单的方法来解决我的问题

在本例中,您可以更改文本框中的值,检查将被更新,但不能以其他方式更新。这有点疯狂,代码在我的开发机器上运行,但不在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);
                });
            });
        }
    }
};
});
app.directive('ngCheckboxFlags',函数(){
返回{
限制:“A”,
要求:'ngModel',
链接:功能(范围、元素、属性、ctrls){
var flagSum;
var复选框=[];
//触发NGM模型的变化
范围$watch(attrs.ngModel,函数(值){
flagSum=值;
对于(变量i=0,ii=checkbox.length;icheckbox.checked=flagSum&(1不要将
ng模型
直接绑定到基元类型,而是使用对象:

$scope.sum = {
  ofCheckValues: 3
};
在HTML上:

ng-model="sum.ofCheckValues"
“当你有ng模型的时候,一定有一个点在那里。如果你没有一个点,你就做错了。”


plunker

找到了一种更优雅、更短的方式:

我的问题是

  • 没有意识到,每个元素都会调用link()
  • 因此,每次创建新的“范围”(针对每个元素)
  • 我只需要在变量(现在称为checkbox;在第一个版本中是数组)中存储对实际元素的引用,以便在模型更改时更新它(scope.$watch)
  • 我不需要“全局”标志和,只需要复选框绑定中的lokal标志,用于将值转移到范围。$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);
                });
            });
        }
      };
    });
    
    app.directive('ngCheckboxFlags',函数(){
    返回{
    限制:“A”,
    要求:'ngModel',
    链接:功能(范围、元素、属性、ctrls){
    var checkbox=element.find('input[type=checkbox]')[0];
    如果(复选框的类型==“未定义”)
    返回;
    //触发NGM模型的变化
    范围$watch(attrs.ngModel,函数(值){
    
    checkbox.checked=value&(1好吧,您的plunker无法工作,因为您直接绑定到作用域级别。始终绑定到(作用域上的对象的)对象属性。请参见此了解我的意思:。至于您的实际问题,“有更好的方法吗?”,我不是那么专业,所以我要说的是,现在就坚持到底。很有趣!这就是为什么在我的开发机器中它是正确的(我有一个复杂的对象),而不是在plnkr上工作。只是想简化我的问题的代码,因此使用了一个基本类型。最好以后不要这样做:(谢谢你的提示。如上所述(在评论中),这就是为什么我的开发机器可以这样做的原因。但是我仍然不确定我的解决方案是否是角度的好方法,或者是否有一种更“角度的方法”。我只想说这确实帮助了我解决了一个非常类似的问题,所以谢谢你的帖子。