[英]Binding data on a model for dynamic nested forms in angularjs
我正在從json對象生成嵌套表單,例如formObject,並綁定json對象本身的值。 我正在遞歸地解析值並在提交時提取實際數據說dataObject。
我可以像這樣的線性形式檢索dataObject。 http://jsfiddle.net/DrQ77/80/ 。
<select ng-model="Answers[question.Name]" ng-options="option for option in question.Options">
與上面相反, http://jsfiddle.net/DrQ77/92/有一些遞歸。 我已將question
重命名為element
,以表示問題和部分。 每個部分都可以有多個問題,並且可以有多個部分(這就是我的嵌套意思)。 我最終想要的是一個下面形式的對象,具有任何嵌套級別。
Answers=[{
section:"Personal",
values:[{GenderQuestion:"Male"},{MaritalStatus:"Married"},{section:"Sub Personal",values:[{LivingWith:"Alone"}]}]
}, {
section:"Random",
values:[{ColorQuestion:"Red"}],
},
{SectionLess:"opt1"}]
這是一個解決方案,我可以在提交,$ scope.Answers從第一小提琴獲得它不(我認為)允許這種嵌套。 但是當我必須更新現有的dataObject時,我覺得需要在渲染之前將dataObject映射到formObject,然后在提交時再次解析。 現在這不是MVC,看起來不優雅(由於遞歸)而且我認為這有一個“有角度的方式”。
有沒有人試過這個並讓它以更好的方式工作? 我該如何解決這個問題?
不是很漂亮,但這是你已經提出的解決方案的替代方案。
function QuestionController($scope) {
$scope.answers = {};
$scope.tempOption = "";
$scope.questions = [
{
"text": "Gender?",
"name": "GenderQuestion",
"options": ["Male", "Female"]},
{
"text": "Favorite color?",
"name": "ColorQuestion",
"options": ["Red", "Blue", "Green"]}
];
$scope.showAnswers = function () {
console.log($scope.answers);
};
$scope.pumpOption = function (name, tempOption) {
$scope.answers[name] = tempOption;
};
};
<ul ng-repeat="question in questions">
<li>
<div>{{question.text}}</div>
<select ng-model="tempOption" ng-options="opt for opt in question.options" ng-change="pumpOption(question.name, tempOption)">
</select>
</li>
</ul>
我們將select標記中所選選項的值綁定到$ scope.tempOption變量。
然后我們在這個select標簽上監聽ng-change事件,我們運行一個函數,該函數接受$ scope.tempOption變量加上與select標簽關聯的{{question.name}}。
然后,此函數將answers [name]設置為$ scope.tempOption的當前值。
希望這對你有用,祝你好運:)
var model = {
colors:["Red","Blue","Green","Black","White"],
genders:["Male", "Female"],
topic:["Gender", "Color"],
category:["Favorite", "Least favorite"],
};
function makeQuestion(topic, category){
return (category+1 ? model.category[category] + ' ' : '')
+ ' ' + model.topic[topic] + '?'
}
function QuestionController($scope){
$scope.Answers = {};
$scope.Questions = [
{
"Text": makeQuestion(0),
"Name": "GenderQuestion",
"Options": model.genders
},{
"Text": makeQuestion(1,0),
"Name": "ColorQuestion",
"Options": model.colors.slice(0,3)
},{
"Text": makeQuestion(0,1),
"Name": "SexistQuestion",
"Options": model.genders
},{
"Text": makeQuestion(1,1),
"Name": "RacistQuestion",
"Options":model.colors.slice(3)
}
];
$scope.ShowAnswers = function()
{
console.log($scope.Answers);
};
}
好吧,我在開玩笑。 但是你嘗試過使用平面相關對象關系表方法而不是嵌套嗎?
{
sections:[
{ "Name": 'Personal', "questions":[0], sub:[1] },
{ "Name": 'SubPersonal', "questions":[3], sub:[]},
{ "Name": 'Random', "questions":[1,2], sub:[] }
],
questions:[
{ "Name":"Gender", "Text":"Gender?", "Options":["Male", "Female"] },
{ "Name":"Color", "Text":"Favorite Color?", "Options":["Red","Blue","Green"] },
{ "Name":"LivingWith", "Text":"Living With?", "Options":["Alone","Someone"] },
{ "Name":"Random", "Text":"SectionLess", "Options":["opt1", "opt2"] }
]
}
只需創建$scope.Answer = {};
並將ng-model鏈接到它。 http://jsfiddle.net/2AwLM/40/
好的 - 這並不像我最初想的那么簡單,所以我希望它是你所追求的 - 你會想要使用一個動態生成其模板HTML的指令(更好的是,使用templateUrl和一個傳入類型的函數)
TLDR:請參閱http://jsfiddle.net/cirrusinno/SzaNW/2上的小提琴
HTML非常簡單
<div ng-controller="questionsController">
<!-- for each question, render section or question -->
<div ng-repeat="item in Questions">
<!-- we ignore section here as it's a root section -->
<question item="item"></question>
</div>
您需要創建一個可以呈現問題和部分的指令。 它還需要跟蹤該部分,以便它可以構建答案
.directive('question', ['$compile', '$templateCache', function ($compile, $templateCache) {
var generateHtmlTemplate = function (item, section) {
return item.type != 'section' ?
// render the question
'question ' + item.name + '<br/>' +
'<select ng-model="optionValue" ng-options="opt for opt in item.options" ng-change="pushAnswer(item.name, section, optionValue)"></select>' :
// or the template for a section
'<br/><hr/>section ' + item.sectionName + '<br/>' +
'<div ng-repeat="q in item.questions"><question item="q" section="item"></question></div><hr/>';
}
var currentSection = null;
return {
scope: {
item: '=',
section: '='
},
restrict: 'E',
link: function ($scope, element, attrs) {
// check current section
if ($scope.item.type == 'section') {
// set new current section
$scope.currentSection = $scope.item;
} else {
// use section passed in from parent section
$scope.currentSection = $scope.section;
}
// get template html
var t = generateHtmlTemplate($scope.item, $scope.currentSection);
// set the scope function to set the value
$scope.pushAnswer = function (q, section, value) {
// build the Answers object here however you want...
if (section != null) {
console.log('pushAnswer q=' + q.name + ' - section=' + section.sectionName + ' - value=' + value);
} else {
console.log('pushAnswer q=' + q.name + ' - section=rootSection - value=' + value);
}
};
// chuck it into element as template
element.html(t);
// compile it up and return it
$compile(element.contents())($scope);
},
};
}])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.