我正在从json对象中生成嵌套的形式,并绑定了json对象本身中的值。我正在递归地解析这些值,并在提交中删除了实际数据表明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
,以表示问题&amp;部分。每个部分都可以有多个问题&amp;同样,多个部分(这是我嵌套的意思)。我最终想要的是以下任何层次的形式的对象。
Answers=[{
section:"Personal",
values:[{GenderQuestion:"Male"},{MaritalStatus:"Married"},{section:"Sub Personal",values:[{LivingWith:"Alone"}]}]
}, {
section:"Random",
values:[{ColorQuestion:"Red"}],
},
{SectionLess:"opt1"}]
这是一种解决方案&amp;我可以在提交时得到它,第一个小提琴的$ scope.swers(我认为)不允许这种筑巢。但是,当我必须更新现有的dataObject时,我觉得需要在渲染之前将dataObject映射到formObject上,然后在提交中再次解析。现在,这不是MVC,看起来不优雅(由于递归)&amp;我认为这有一种"角度"。
是否有人尝试过此&amp;让它以更好的方式工作?我该如何解决?
不是很漂亮,但这是您已经提出的解决方案的替代方法。
http://jsfiddle.net/drq77/84/
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>
我们将选择标签中选定选项的值绑定到$ scope.tempoption变量。
然后,我们聆听此选择标签上发生的ng-change事件,其中我们运行一个函数,该函数采用$ scope.tempoption variable加上{{Question.name}}与选择标签关联的{{Question.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模型链接到它。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>
您需要创建一个可以同时提出问题的指令&amp;部分。它还需要跟踪该部分,以便可以构建答案
.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);
},
};
}])