/ / Formularz dynamiczny przy użyciu AngularJS, wiązanie wielu wartości - angularjs, formularze

Forma dynamiczna przy użyciu AngularJS, wiązanie wielu wartości - angularjs, formularze

Szukam najlepszego sposobu na przekształcenie formy statycznej w formę dynamiczną kątową. Nie jestem pewien, jak powiązać wiele wartości z tą samą odpowiedzią.

Strona statyczna dostępna jest pod adresem: 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>

Plik 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
]
}
]

Odpowiedzi:

0 dla odpowiedzi № 1

Sprawy byłyby znacznie prostsze, gdyby można było użyć wielokrotnego wyboru, ale rozumiem, że interakcja użytkownika może być trudna (rozważ coś w stylu md-select, który przekształca wielokrotne zaznaczenie w listę pól wyboru dla Ciebie)

Wybór wielokrotny:

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

W każdym razie użycie pola wyboru HTML jest całkowicie w porządku. Aby to zrobić, musielibyśmy jak zwykle powiązać model pola wyboru z danymi, a następnie jednocześnie zaktualizować tablicę odpowiedzi.

ng-model="o.selected"

ng-change="updateAnswer(i)"

Ponadto podczas inicjowania będziemy musieli skopiować istniejące dane do modelu.

ng-init="initMultiple(i)"

Działający kod:

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 dla odpowiedzi nr 2

Bazując na moim doświadczeniu dokonam separacjijako dwa modele Angulara (lub zwykle nazywane usługami) dla pytań formularzowych i drugi, który zbierze odpowiedzi i ostatecznie zostanie przekazany do backendu do dalszego przetwarzania. Zapewni mi to elastyczność w utrzymaniu zarówno logiki, jak i prezentacji.

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

Z powyższego przykładu modeli usług musisz je udostępnić w swojej prezentacji za pośrednictwem kontrolera Angular z Dependency Injection.

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

To, co piszesz na stronie HTML jako widok Angular, jest już wystarczająco bliskie. Wystarczy zmienić wiązanie na dwa modele, jak proponuję powyżej. Dziękuję Ci.