/ / Formulário dinâmico usando AngularJS, vinculação de valores múltiplos - angularjs, formulários

Forma dinâmica usando AngularJS, vários valores de ligação - angularjs, formulários

Estou procurando a melhor abordagem para converter uma forma estática em uma forma dinâmica angular. Não tenho certeza de como vincular vários valores à mesma resposta.

A página estática está disponível em: 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>

O arquivo 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
]
}
]

Respostas:

0 para resposta № 1

As coisas seriam muito mais simples se você pudesse usar uma seleção múltipla, mas eu entendo que pode ser difícil para o usuário interagir (considere algo como md-select, que transforma a seleção múltipla em uma lista de caixas de seleção para você)

Seleção múltipla:

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

De qualquer forma, está tudo bem usar a caixa de seleção HTML. Para fazer isso, precisaríamos vincular o modelo de caixa de seleção aos dados como de costume e, em seguida, atualizar a matriz de resposta simultaneamente.

ng-model="o.selected"

ng-change="updateAnswer(i)"

Além disso, precisaremos copiar os dados existentes para o modelo durante o init.

ng-init="initMultiple(i)"

Código de trabalho:

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


0 para resposta № 2

Com base na minha experiência, farei uma separaçãocomo dois modelos angulares (ou geralmente chamados de serviços) para as perguntas do formulário e outro que coletará as respostas e, eventualmente, será passado para o backend para processamento posterior. Isso me dará flexibilidade para manter a lógica e a apresentação.

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

A partir do exemplo de modelos de serviço acima, você precisa disponibilizá-los para sua apresentação por meio do controlador Angular com injeção de dependência.

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

O que você escreve na página HTML como uma visualização angular já está perto o suficiente. Você só precisa alterar a ligação para dois modelos, como proponho acima. Obrigada.