使用AngularJS的动态表单,多个值绑定

时间:2017-09-12 01:18:01

标签: angularjs forms

我正在寻找将静态表单转换为角度动态表单的最佳方法。我不确定如何将多个值绑定到同一个答案。

静态页面位于:https://jsfiddle.net/hvuq5h46/

<div ng-repeat="i in items">
     <select ng-model="i.answer" ng-options="o.id as o.title for o in i.answersAvailable" ng-visible="y.TYPE = 'SINGLE'"></select>
     <input type="checkbox" ng-model="i.answer" ng-visible="y.TYPE = 'MULTIPLE'" />
</div>

JSON文件

[
  {
    "id": 1,
    "title": "Are you a student?",
    "type": "SINGLE",
    "answersAvailable": [
      {
        "id": 1,
        "title": "Yes"
      },
      {
        "id": 2,
        "title": "No"
      }
    ],
    "answer": [
      1
    ]
  },
  {
    "id": 2,
    "title": "Would you like to be an astronaut?",
    "type": "SINGLE",
    "answersAvailable": [
      {
        "id": 4,
        "title": "Yes"
      },
      {
        "id": 5,
        "title": "No"
      },
      {
        "id": 6,
        "title": "I am not sure"
      }
    ],
    "answer": [
      4
    ]
  },
  {
    "id": 3,
    "title": "What is your favourite planet?",
    "type": "MULTIPLE",
    "answersAvailable": [
      {
        "id": 7,
        "title": "Earth"
      },
      {
        "id": 8,
        "title": "Mars"
      },
      {
        "id": 9,
        "title": "Jupiter"
      }
    ],
    "answer": [
      7,
      8
    ]
  }
]

2 个答案:

答案 0 :(得分:0)

根据我的经验,我将分别作为形式问题的两个Angular模型(或通常称为服务),另一个将收集答案并最终传递到后端进行进一步处理的模型。这将为我提供维护逻辑和演示的灵活性。

var myModule = angular.module('myModule', []); 
myModule.factory('QuestionsFormService', function() {
  var _question1;
  var _question2;
  var _question3;

  function init(data){
     //questions initiation
  }

   return init;
});

var myModule = angular.module('myModule', []); 
myModule.factory('FormDataService', function() {
   var _dataAnswer = {}

   function init(){
      //data initialization
   }

   function insertData(key, value){
      _dataAnswer[key] = value
   }
   return init;
});

从上面的服务模型示例中,您需要通过具有依赖注入的Angular控制器使这些可用于演示文稿。

myModule.controller("MyCtrl", function($scope, FormDataService, QuestionsFormService) {
  $scope.form_questions = QuestionsFormService.init();
  $scope.form_answers = FormDataService.init()
  //further logic to make these available on your view on your convenience
});

您在HTML页面上作为Angular视图编写的内容已经足够接近。您只需要将绑定更改为两个模型,如上所述。谢谢。

答案 1 :(得分:0)

如果您可以使用多重选择,事情就会简单得多,但我知道用户可能很难进行交互(考虑像md-select之类的东西,它会将多个选项转换为您的复选框列表)< / p>

多重选择:

<select multiple
  ng-model="i.answer"
  ng-options="o.id as o.title for o in i.answersAvailable"
  ng-if="i.type == 'MULTIPLE'"></select>

无论如何,使用HTML复选框是完全可以的。为此,我们需要像往常一样将复选框模型绑定到数据中,然后同时更新答案数组。

ng-model="o.selected"

ng-change="updateAnswer(i)"

此外,我们还需要在初始化期间将现有数据复制到模型中。

ng-init="initMultiple(i)"

工作代码:

&#13;
&#13;
angular.module('test', []).controller('Test', Test);

function Test($scope) {
  $scope.items = [{
      "id": 1,
      "title": "Are you a student?",
      "type": "SINGLE",
      "answersAvailable": [{
          "id": 1,
          "title": "Yes"
        },
        {
          "id": 2,
          "title": "No"
        }
      ],
      "answer": [
        1
      ]
    },
    {
      "id": 2,
      "title": "Would you like to be an astronaut?",
      "type": "SINGLE",
      "answersAvailable": [{
          "id": 4,
          "title": "Yes"
        },
        {
          "id": 5,
          "title": "No"
        },
        {
          "id": 6,
          "title": "I am not sure"
        }
      ],
      "answer": [
        4
      ]
    },
    {
      "id": 3,
      "title": "What is your favourite planet?",
      "type": "MULTIPLE",
      "answersAvailable": [{
          "id": 7,
          "title": "Earth"
        },
        {
          "id": 8,
          "title": "Mars"
        },
        {
          "id": 9,
          "title": "Jupiter"
        }
      ],
      "answer": [
        7,
        8
      ]
    }
  ]
  
  $scope.initMultiple = function(item) {
    item.answersAvailable.forEach(function(option) {
      option.selected = item.answer.indexOf(option.id) != -1;
    });
  }
  
  $scope.updateAnswer = function(item) {
    item.answer = item.answersAvailable.filter(function(option) {
      return option.selected;
    })
    .map(function(option) {
      return option.id;
    });
  }
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app='test' ng-controller='Test'>
  <div ng-repeat="i in items">
    <select ng-model="i.answer[0]"
      ng-options="o.id as o.title for o in i.answersAvailable"
      ng-if="i.type == 'SINGLE'"></select>

    <label ng-repeat="o in i.answersAvailable" 
      ng-if="i.type == 'MULTIPLE'"
      ng-init="initMultiple(i)">

      <input type="checkbox" 
        ng-model="o.selected" 
        ng-change="updateAnswer(i)" /> {{o.title}}
    </label>
    <div>{{i.answer}}</div>
  </div>
</div>
&#13;
&#13;
&#13;