【问题标题】:AngularJS using ngModel to get complex object from Checkbox setAngularJS 使用 ngModel 从 Checkbox 集中获取复杂对象
【发布时间】:2014-03-09 08:51:03
【问题描述】:

早安!

我在堆栈上找到了几篇涉及此内容的帖子,但我还没有找到任何可以完成我正在尝试做的事情的帖子。

(JS Fiddle 供参考:http://jsfiddle.net/gsLXf/1/

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

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 有这样一种很好的方式来动态创建响应对象时,这似乎有点过头了(这种情况除外) .

最好的方法是什么?

【问题讨论】:

  • 如果您最初将答案 ID 放在响应中,那没问题:jsfiddle.net/Uh2Gc
  • 感谢您的评论,但除非您可以根据问题对象向我展示一些动态执行此操作的方法,否则这将不起作用。所有这些都是由数据库和中间层 API 驱动的,所以我不能将任何东西手动/硬编码到控制器中(比如将该对象添加到响应对象中。
  • 现在是动态的:jsfiddle.net/Uh2Gc/1
  • @stefchri - 伙计,这越来越近了!而且那个foreach很棒,这将使我将来不会遇到任何麻烦!你能帮我做一件额外的事情吗(对原始问题的一些扩展)。现在,复选框对象上的数组仅捕获真/假而不是该选项的值。有什么方法可以让它获取值(选项 ID)?非常感谢
  • jsfiddle.net/Uh2Gc/2 解决了你的小问题:ng-true-value

标签: javascript angularjs checkbox angular-ngmodel


【解决方案1】:

我在现有的 Angular 指令和 html 上尽了最大努力,但是当未选中复选框时,数组中仍然有多余的空字符串。

我使用ng-init

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

jsfiddle:

http://jsfiddle.net/P9dsR/

【讨论】:

  • 这并没有完全解决我的问题,但 +1 让我可以更轻松地搭建对象,而无需遍历我的问题对象!
【解决方案2】:

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

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

<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);
        }
    };
});

【讨论】:

  • 感谢@Nikos,我简化了 Fiddle 的设置,但实际上我已经有几个指令可以通过模板生成这个调查。我会尝试把你在这里得到的东西回填到我的代码中!这看起来是一个很好的解决方案,所以我会看看我能从中得到什么。
  • 完美集成!我能够毫无问题地将其应用到我的模板中,这绝对是所有响应中最干净的实现。感谢您的帮助@Nikos
猜你喜欢
  • 2021-06-27
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多