【问题标题】:Angular two-way-binding with sub elements与子元素的角度双向绑定
【发布时间】:2013-02-14 12:39:29
【问题描述】:

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

我想用一个 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);
                });
            });
        }
    }
};
});

请提前 胡桃

【问题讨论】:

  • 好吧,你的 plunker 没有工作,因为你直接绑定到范围级别。始终绑定到对象属性(范围内对象的)。看到这个来理解我的意思:plnkr.co/edit/jgoMWDssothUlSy1oelP?p=preview。至于您的实际问题,“有没有更好的方法?”,我不是那么专家,所以我会说坚持现在有效的方法。
  • 好笑!正是这就是为什么它在我的开发机器中是正确的(我有一个复杂的对象)而不是在 plnkr 上工作。只是想简化我的问题的代码,因此使用了原始类型。以后最好不要这样做:(

标签: checkbox angularjs model-binding angularjs-directive


【解决方案1】:

找到了更优雅更短的方式:http://plnkr.co/edit/9h7EkEpDohXTniIDHdc5

我的问题是

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

【讨论】:

  • 只想说这真的帮助我解决了一个非常相似的问题,所以感谢发帖。
【解决方案2】:

不要将ng-model 直接绑定到原始类型,而是使用对象:

$scope.sum = {
  ofCheckValues: 3
};

在 HTML 上:

ng-model="sum.ofCheckValues"

“只要你有 ng-model,就一定会有一个点。如果你没有点,那你就做错了。”

plunkerhttp://plnkr.co/edit/NRAk3kyP1rdDmYrsz6ZL?p=preview

【讨论】:

  • 感谢您的提示。如上所述(在评论中),这就是为什么它在我的开发机器中没问题。但我仍然不确定我的解决方案是否是角度的好方法,或者是否有更“角度的方式”。
猜你喜欢
  • 2019-02-16
  • 2019-08-18
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
  • 2015-12-02
  • 1970-01-01
  • 2015-08-30
  • 2018-06-19
相关资源
最近更新 更多