/ / Forma dinámica usando AngularJS, enlace de valores múltiples - angularjs, formas

Forma dinámica usando AngularJS, enlace de valores múltiples - angularjs, formas

Estoy buscando un mejor enfoque para convertir una forma estática en una forma dinámica angular. No estoy seguro de cómo vincular múltiples valores a la misma respuesta.

La página estática está disponible en: 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>

El archivo 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
]
}
]

Respuestas

0 para la respuesta № 1

Las cosas serían mucho más simples si pudieras usar una selección múltiple, pero entiendo que podría ser difícil para el usuario interactuar (considera algo como md-select, que transforma la selección múltiple en una lista de casillas de verificación para usted)

Selección múltiple:

<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 todos modos, está completamente bien usar la casilla de verificación HTML. Para hacer eso, necesitaríamos vincular el modelo de casilla de verificación a los datos como de costumbre, y luego actualizar la matriz de respuestas simultáneamente.

ng-model="o.selected"

ng-change="updateAnswer(i)"

Además, necesitaremos copiar los datos existentes al modelo durante init.

ng-init="initMultiple(i)"

Código de trabajo:

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 la respuesta № 2

Basado en mi experiencia, haré una separacióncomo dos modelos angulares (o generalmente llamados servicios) para las preguntas del formulario y otro que recogerá las respuestas y, finalmente, se pasará al back-end para su posterior procesamiento. Esto me proporcionará una flexibilidad para mantener tanto la lógica como la presentación.

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 del ejemplo de los modelos de servicio anteriores, debe ponerlos a disposición de su presentación a través del controlador angular con inyección de dependencia.

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

Lo que escribe en la página HTML como una vista angular ya está lo suficientemente cerca. Solo necesita cambiar el enlace a dos modelos como propongo anteriormente. Gracias.