AngularJS使用ngModel从Checkbox集中获取复杂对象

时间:2014-02-11 14:04:01

标签: javascript angularjs checkbox angular-ngmodel

早上好!

我在堆栈上发现了几个触及此帖子的帖子,但我没有找到任何完成我正在尝试做的事情。

(JS小提琴参考:http://jsfiddle.net/gsLXf/1/

作为调查的一部分,我有一系列动态问题。我已经想出如何将文本和无线电响应中的响应绑定到我可以发回给我的服务器的“响应”对象。我遇到的问题是Checkboxes。正如你在小提琴中看到的那样,当我尝试做的时候

ng-model="response[question.id]"

我的所有复选框都作为一个项目响应(这是有意义的,因为它们都绑定到相同的值。但是,当我使用

ng-model="response[question.id][option.id]"

我弹出一个错误,因为question.id尚未实例化,因此无法将option.id推送到对象上。

理想情况下,我引用的小提琴的响应对象如下所示:

{
   "123456": "2", //radio question
   "789012": //checkbox question 
       ["5", "6"] //list of checkbox options ids selected
}

我的用户将动态创建表单,因此我必须能够在所有情况下都非常优雅地处理它。我无法将任何与对象相关的数据硬编码到控制器中,我也无法手工创建模型对象来处理这种情况。

我已经考虑过循环遍历已知的ID集来构建一个在初始化期间要填充的响应对象,但是当Angular有一个很好的方法来动态创建一个响应对象时(这种情况除外)似乎有点过分了。

这样做的最佳方式是什么?

2 个答案:

答案 0 :(得分:2)

这是一个做你想做的事的小提琴:http://jsfiddle.net/2jVtH/

我已使用名为cbb的指令替换整个HTML,用作:

<div cbb question="question" response="response"></div>

(这使得原始代码也更清晰,恕我直言,这意味着我会对单选按钮做同样的事情)

该指令使用一个独立的作用域,并在其中放置一个接收复选框值的对象:

scope.model = {}

此对象上的深$watch使用值更新数组,因此您可以获得所需的response = { "789012": ["7", "8"] }格式。

指令完整代码:

surveyApp.directive("cbb", function() {
    return {
        restrict: "A",
        scope: {
            question: "=",
            response: "="
        },
        template:
            "<div class='text'>{{question.question}}</div>" +
            '<div class="options" ng-repeat="option in question.options">' +
                '<input type="checkbox" ng-model="model[option.id]" value="{{option.id}}"/> {{option.value}}' +
                '<tags ng-if="option.tags"></tags>' +
                '<action ng-if="option.action"></action>' +
            '</div>',
        link: function(scope, element, attrs) {
            if( !scope.response[scope.question.id] ) {
                scope.response[scope.question.id] = [];
            }
            var result = scope.response[scope.question.id];
            scope.model = {};
            scope.$watch("model", function(newval) {
                var x;
                result.splice(0);
                for( x in newval ) {
                    if( !newval.hasOwnProperty(x) ) continue;
                    if( newval[x] ) result.push(x);
                }
            }, true);
        }
    };
});

答案 1 :(得分:1)

我在现有的Angular指令和html上尽我所能,但当复选框未选中时,它仍然在数组中有冗余的空字符串。

我使用ng-init

ng-init="response[question.id] = []"

的jsfiddle:

http://jsfiddle.net/P9dsR/