Angular 具有 JSON 对象的单页应用程序取决于另一个对象的选择

Angular Single Page App with JSON Object Depending on the Selection of Another

我正在整理一份问卷。每个问题都有三个选项可供选择。每个包含问题的对象都有另一个名为 'dependsOn' 的对象。 例如,如果在问题 1 上选择 "Yes",则将显示以下两个问题,否则将跳过它们。 感谢您对这个小应用程序的任何帮助、想法和建议。 这是我放在一起的 CodePen:my codepen

<div class="main" ng-app="MyApp">

<div ng-controller="AppCtrl as q">

<h1>{{ q.title }}</h1>

<form name="collection" novalidate>

    <div class="questionnaire">

        <div class="questions">

            <div class="question" ng-repeat="question in q.questions" ng-show="question.hrsQuestionOrderNumber === q.currentQuestion">
                <h2>Question {{ question.hrsQuestionOrderNumber }} <span>of {{ q.questions.length }}</span></h2>
                <p>
                    {{ question.descriptionLong }}
                </p>

                <ng-form name="subForm{{question.questionID}}" class="options">
                    <md-radio-group ng-model="question.hrsAnswerId" ng-change="q.watchForm(subForm{{ q.currentQuestion }})" required>
                      <md-radio-button ng-repeat="option in question.choiceModels" ng-value="option.description" required>
                        {{ option.description }}
                      </md-radio-button>
                    </md-radio-group>
                </ng-form>
            </div>

        </div>

        <nav class="clearfix">
          <md-button class="md-primary md-raised" ng-click="q.questionChange('prev')" ng-disabled="q.prev">Previous</md-button>
          <md-button class="md-primary md-raised" ng-click="q.questionChange('next')" ng-disabled="q.next">Next</md-button>
        </nav>
    </div>

</form>

Angular代码:

angular
.module('MyApp',['ngMaterial', 'ngMessages'])
.controller('AppCtrl', function($timeout, $scope) {

const context = this;

context.title = 'Questionnaire with Questions Depending on Choices';
context.currentQuestion = 1;
context.next = true;
context.prev = true;
context.nextButton = true;

context.form = $scope.collection;

function disableButton () {

    if (context.currentQuestion === 1) {
        context.prev = true;
        context.next = false;
    } else {
        context.prev = false;
        context.next = false;
    }
};

context.questionChange = function (go) {

    if (go === 'prev') {
        context.currentQuestion = context.currentQuestion - 1;
    }

    if (go === 'next') {

        context.currentQuestion = context.currentQuestion + 1;

        $timeout(function () {
            context.next = true;
        });
    }

    disableButton();
};

context.watchForm = function (currentForm) {

  if (currentForm.$invalid === false) {

    if (context.currentQuestion !== context.questions.length) {
      context.next = false;
    }
  } else {
    console.log('form NOT in scope');
  }

};

context.questions = [
            {
              "questionID": 1,
              "hrsQuestionOrderNumber": 1,
              "descriptionLong": "Do you collect money from anyone (students, employees, or other sources)?",
              "choiceModels": [
                {
                  "description": "Yes",
                  "answerId": 1
                },
                {
                  "description": "No",
                  "answerId": 1
                },
                {
                  "description": "None / Not applicable",
                  "answerId": 3
                }
              ],
              "dependsOn": null
            },
            {
              "questionID": 2,
              "hrsQuestionOrderNumber": 2,
              "descriptionLong": "Are pre-numbered receipts given to the person paying money? If individual receipts are not given, do you use an approved PBO/S&I collection document?",
              "choiceModels": [
                {
                  "description": "Yes",
                  "answerId": 1
                },
                {
                  "description": "No",
                  "answerId": 1
                },
                {
                  "description": "None / Not applicable",
                  "answerId": 3
                }
              ],
              "dependsOn": {
                "hrsQuestionId": 0,
                "hrsQuestionLink": 1,
                "hrsAnswerId": 1
              }
            },
            {
              "questionID": 3,
              "hrsQuestionOrderNumber": 3,
              "descriptionLong": "Do cash receipts or logs contain sufficient detail to accurately describe the nature of the transaction?",
              "choiceModels": [
                {
                  "description": "Yes",
                  "answerId": 1
                },
                {
                  "description": "No",
                  "answerId": 1
                },
                {
                  "description": "None / Not applicable",
                  "answerId": 3
                }
              ],
              "dependsOn": {
                "hrsQuestionId": 0,
                "hrsQuestionLink": 1,
                "hrsAnswerId": 1
              }
            },
            {
              "questionID": 4,
              "hrsQuestionOrderNumber": 4,
              "descriptionLong": "Do receipts or logs identify individuals and not groups of individuals (such as a class)?",
              "choiceModels": [
                {
                  "description": "Yes",
                  "answerId": 1
                },
                {
                  "description": "No",
                  "answerId": 1
                },
                {
                  "description": "None / Not applicable",
                  "answerId": 3
                }
              ],
              "dependsOn": null
            },
            {
              "questionID": 5,
              "hrsQuestionOrderNumber": 5,
              "descriptionLong": "For money collected, is it always deposited and never used for purchases?",
              "choiceModels": [
                {
                  "description": "Yes",
                  "answerId": 1
                },
                {
                  "description": "No",
                  "answerId": 1
                },
                {
                  "description": "None / Not applicable",
                  "answerId": 3
                }
              ],
              "dependsOn": {
                "hrsQuestionId": 0,
                "hrsQuestionLink": 4,
                "hrsAnswerId": 1
              }
            },
            {
              "questionID": 6,
              "hrsQuestionOrderNumber": 6,
              "descriptionLong": "For money not yet deposited, is it kept in a secure location?",
              "choiceModels": [
                {
                  "description": "Yes",
                  "answerId": 1
                },
                {
                  "description": "No",
                  "answerId": 1
                },
                {
                  "description": "None / Not applicable",
                  "answerId": 3
                }
              ],
              "dependsOn": {
                "hrsQuestionId": 0,
                "hrsQuestionLink": 4,
                "hrsAnswerId": 1
              }
            },
            {
              "questionID": 7,
              "hrsQuestionOrderNumber": 7,
              "descriptionLong": "Do you keep a file of original deposit documentation—including cash receipts or logs—together?",
              "choiceModels": [
                {
                  "description": "Yes",
                  "answerId": 1
                },
                {
                  "description": "No",
                  "answerId": 1
                },
                {
                  "description": "None / Not applicable",
                  "answerId": 3
                }
              ],
              "dependsOn": {
                "hrsQuestionId": 0,
                "hrsQuestionLink": 4,
                "hrsAnswerId": 1
              }
            }
          ];

})
.config(function($mdIconProvider) {
});

我不明白你的问题是什么?

  1. 创建将包含问题数量作为键和答案索引作为值的对象

    {'1': 1, '2': 0, ...}

  2. 每次回答后,您只需浏览一系列问题,select下一个问题取决于用户选择的内容。

我的解决方案是遍历问题并评估问题是否取决于所选答案。这使得可以根据所选答案跳过一些问题。 这是我的 CodePen:My CodePend

angular
.module('MyApp', ['ngMaterial', 'ngMessages'])
.controller('AppCtrl', function ($timeout, $scope, $filter) {

    const context = this;

    context.title = 'Questions Depending on Choices';
    context.heading = 'Questionnaire';
    context.currentQuestion = 1;
    context.next = true;
    context.prev = true;
    context.nextButton = true;

    function disableButton() {

        if (context.currentQuestion === 1) {
            context.prev = true;
            context.next = false;
        } else {
            context.prev = false;
            context.next = false;
        }
    };

    context.questionChange = function(go) {

        if (go === 'prev') {

            context.currentQuestion = context.currentQuestion - 1;
            //Go to the prev (in order) that has an selectedAnswer
            var prevQuestions = $filter("filter")(context.questions, { "hrsQuestionOrderNumber": context.currentQuestion });
            if (!prevQuestions[0].hrsAnswerId) {
                context.questionChange(go);
            }
        }

        if (go === 'next') {
            //in order - check the dependsOn for Q&a required

            context.currentQuestion = context.currentQuestion + 1;
            var nextQuestions = $filter("filter")(context.questions, { "hrsQuestionOrderNumber": context.currentQuestion });
            if (nextQuestions.length > 0) {
                var dependsOn = nextQuestions[0].dependsOn;
                if (dependsOn) {
                    var dependentQuestions = $filter("filter")(context.questions, { "questionID": dependsOn.hrsQuestionLink });
                    if (dependentQuestions[0].hrsAnswerId !== dependsOn.hrsAnswerId) {
                        context.questionChange(go);
                    }
                }
            }

            $timeout(function () {
                context.next = true;
            });
        }

        disableButton();
    };

    context.watchForm = function(currentForm) {

        if (currentForm.$invalid === false) {

            if (context.currentQuestion !== context.questions.length) {
                context.next = false;
            }
        } else {
            console.log('form NOT in scope');
        }

    };



    context.questions = [
        {
            "questionID": 1533,
            "hrsQuestionOrderNumber": 1,
            "descriptionLong": "Do you collect money from anyone (students, employees, or other sources)?",
            "choiceModels": [
                {
                    "description": "Yes",
                    "answerId": 1000
                },
                {
                    "description": "No",
                    "answerId": 1001
                },
                {
                    "description": "None / Not applicable",
                    "answerId": 1148
                }
            ],
            "dependsOn": null
        },
        {
            "questionID": 1534,
            "hrsQuestionOrderNumber": 2,
            "descriptionLong": "Are pre-numbered receipts given to the person paying money? If individual receipts are not given, do you use an approved PBO/S&I collection document?",
            "choiceModels": [
                {
                    "description": "Yes",
                    "answerId": 1000
                },
                {
                    "description": "No",
                    "answerId": 1001
                },
                {
                    "description": "None / Not applicable",
                    "answerId": 1148
                }
            ],
            "dependsOn": {
                "hrsQuestionId": 0,
                "hrsQuestionLink": 1533,
                "hrsAnswerId": 1000
            }
        },
        {
            "questionID": 1535,
            "hrsQuestionOrderNumber": 3,
            "descriptionLong": "Do cash receipts or logs contain sufficient detail to accurately describe the nature of the transaction?",
            "choiceModels": [
                {
                    "description": "Yes",
                    "answerId": 1000
                },
                {
                    "description": "No",
                    "answerId": 1001
                },
                {
                    "description": "None / Not applicable",
                    "answerId": 1148
                }
            ],
            "dependsOn": {
                "hrsQuestionId": 0,
                "hrsQuestionLink": 1533,
                "hrsAnswerId": 1000
            }
        },
        {
            "questionID": 1536,
            "hrsQuestionOrderNumber": 4,
            "descriptionLong": "Do receipts or logs identify individuals and not groups of individuals (such as a class)?",
            "choiceModels": [
                {
                    "description": "Yes",
                    "answerId": 1000
                },
                {
                    "description": "No",
                    "answerId": 1001
                },
                {
                    "description": "None / Not applicable",
                    "answerId": 1148
                }
            ],
            "dependsOn": null
        },
        {
            "questionID": 1537,
            "hrsQuestionOrderNumber": 5,
            "descriptionLong": "For money collected, is it always deposited and never used for purchases?",
            "choiceModels": [
                {
                    "description": "Yes",
                    "answerId": 1000
                },
                {
                    "description": "No",
                    "answerId": 1001
                },
                {
                    "description": "None / Not applicable",
                    "answerId": 1148
                }
            ],
            "dependsOn": {
                "hrsQuestionId": 0,
                "hrsQuestionLink": 1536,
                "hrsAnswerId": 1000
            }
        },
        {
            "questionID": 1538,
            "hrsQuestionOrderNumber": 6,
            "descriptionLong": "For money not yet deposited, is it kept in a secure location?",
            "choiceModels": [
                {
                    "description": "Yes",
                    "answerId": 1000
                },
                {
                    "description": "No",
                    "answerId": 1001
                },
                {
                    "description": "None / Not applicable",
                    "answerId": 1148
                }
            ],
            "dependsOn": {
                "hrsQuestionId": 0,
                "hrsQuestionLink": 1536,
                "hrsAnswerId": 1000
            }
        },
        {
            "questionID": 1539,
            "hrsQuestionOrderNumber": 7,
            "descriptionLong": "Do you keep a file of original deposit documentation—including cash receipts or logs—together?",
            "choiceModels": [
                {
                    "description": "Yes",
                    "answerId": 1000
                },
                {
                    "description": "No",
                    "answerId": 1001
                },
                {
                    "description": "None / Not applicable",
                    "answerId": 1148
                }
            ],
            "dependsOn": {
                "hrsQuestionId": 0,
                "hrsQuestionLink": 1536,
                "hrsAnswerId": 1000
            }
        }
    ];

})
.config(function($mdIconProvider) {
});