我正在写一份问卷调查申请,有回答的问题,这些回答可能有孩子问题,这些问题可能有另一个孩子问题的回答,然后是N级层次结构,我需要找到最好的策略加载到html列表中,使用正常的ng-repeat我有一个级别的限制,在this example我链4个级别,但它可能更多,我感谢任何评论或建议。
var myApp = angular.module('myApp',[]);
myApp.controller('myCtrl',function ($scope){
$scope.questionnaire = [
{
QuestionID: 1,
Description: "Question 1",
Responses: [{
RespDescription: "Response 1"
},
{
RespDescription: "Response 2",
ChildQuestions: [{
QuestionID: 2,
Description: "Child Question 2.1",
Responses: [{
RespDescription: "Child Response 2.1.1"
},
{
RespDescription: "Child Response 2.1.2",
ChildQuestions: [{
QuestionID: 3,
Description: "Child Question 2.1.2.1",
Responses:[{
RespDescription: "Child Response...",
ChildQuestions:[{
QuestionID:4,
Description: "Other Child Question",
Responses:[{
RespDescription: "Response..."
}]
}]
}]
}]
}]
}]
}]
}
];
})
答案 0 :(得分:0)
我已经完成了一个类似的问卷调查类型应用程序。我所要做的就是创建一个具有树状结构关系的后端api。
你希望将它连接到后端并且不仅仅是写出来,否则它会变得非常混乱,很像回调地狱。
Here是github上项目的开始。它使用环回进行数据建模并挂钩到角度前端,但您可以以任何方式使用后端。
idea是当您查询第一个question时,它有一些孩子answers。然后,每个答案都附加了另一个问题,依此类推,依此类推。每个模型的关系在这里都很重要。
通过这种方式,您可以创建一个控制器,当您选择answerA的answerC时,它会在数据库中查询相关的questionC对象,并包含与该新问题C相关联的所有答案。
然后,您将添加新加载的questionC及其对主要问题数组的回答并向下滚动(或类似的内容)。
一个快速的sudo代码示例:
//controller.js
app.controller('questionair', function(Answer, Question){
//Lets load our first question, with the related 3 answers
Question.findById({id: 1}, {include: 'answers'}).$promise
.then(function(question){
$scope.questions = [question];
});
//function that gets new question from our select answer
$scope.answerMe = function(questionId){
Question.findById({id: questionId}, {include: 'answers'}).$promise
.then(function(newQuestion){
$scope.questions.push(newQuestion);
},function(error){
console.log('You\'ve answered the last question!');
});
};
});
//index.html
<div ng-repeat="question in questions">
<h2>{{ question.text }}</h2>
<ul>
<li ng-repeat="answer in question.answers"
ng-click="answerMe(answer.questionId)">
{{ answer.text }}
</li>
</ul>
</div>
答案 1 :(得分:0)
我是通过Mark Lagendijk的code in plunker并且他有这个任务的解决方案,递归是秘密,有一个指令调用本身可能代表一个N级结构,关键是名为的服务RecursionHelper 编译并避免指令中的无限循环,我根据自己的需要调整了代码,这就是结果:
RecursionHelper
/*
* An Angular service which helps with creating recursive directives.
* @author Mark Lagendijk
* @license MIT
*/
angular.module('RecursionHelper', []).factory('RecursionHelper', ['$compile', function($compile){
return {
/**
* Manually compiles the element, fixing the recursion loop.
* @param element
* @param [link] A post-link function, or an object with function(s) registered via pre and post properties.
* @returns An object containing the linking functions.
*/
compile: function(element, link){
// Normalize the link parameter
if(angular.isFunction(link)){
link = { post: link };
}
// Break the recursion loop by removing the contents
var contents = element.contents().remove();
var compiledContents;
return {
pre: (link && link.pre) ? link.pre : null,
/**
* Compiles and re-adds the contents
*/
post: function(scope, element){
// Compile the contents
if(!compiledContents){
compiledContents = $compile(contents);
}
// Re-add the compiled contents to the element
compiledContents(scope, function(clone){
element.append(clone);
});
// Call the post-linking function, if any
if(link && link.post){
link.post.apply(null, arguments);
}
}
};
}
};
}]);
questionTree指令:
directives.directive('questionTree', function (RecursionHelper) {
return {
restrict: "AE",
scope: {
items: "=",
},
priority: 500,
replace: true,
//I use templateURL but for simplicity I used inline template in this code
template: function (el, attr) {
var itemType = attr["itemType"];
if (itemType == "question") {
return '<ul>'+
'<li ng-repeat="item in items">'+
'<div ng- click="loadChildResponses(item);$event.stopPropagation();">{{item.Description}}</div>'+
'<question-tree items="item.Responses" item-type="reponse"></question-tree>'+
'</li>'+
'</ul>';
}
else {
return '<ul>'+
'<li ng-repeat="item in items">'+
'<div ng-click="loadChildQuestions(item);$event.stopPropagation();">{{item.Description}}</div>'+
'<question-tree items="item.ModelWizardQuestions" item-type="question"></question-tree>'+
'</li>'+
'</ul>';
}
},
controller: function ($scope, $http) {
$scope.loadChildResponses = function (item) {
$http.get(siteUrls.GetReponses + "?QuestionID=" + item.QuestionID)
.success(function (data) {
if (data && data.length > 0) {
item.Responses = data;
}
});
};
$scope.loadChildQuestions = function (item) {
$http.get(siteUrls.getChildQuestions + "?ResponseID=" + item.ResponseID)
.success(function (data) {
if (data && data.length > 0) {
item.Questions = data;
}
});
};
},
compile: function (element) {
// Use the compile function from the RecursionHelper,
// And return the linking function(s) which it returns
return RecursionHelper.compile(element);
}
}
});
所以,我加载第一级问题,并附上questionTree指令,应用程序可以加载N级。
HTML:
<ul>
<li ng-repeat="question in Questions">{{question.Description}}
<ul>
<li ng-repeat="response in question.Responses"><span>{{response.Description}}</span>
<question-tree items="response.Questions" item-type="question"></question-tree>
</li>
</ul>
</li>
</ul>