简体   繁体   中英

Array within AngularJS controller is not initialised

I am writing a small dialog controller, that takes a question, a set of answers and marks the index of the correct answer. I need to enable the user to add multiple questions, and store them in an array.

All works, until I try to push the JSON containing details about the question to an array I created earlier. Upon trying to push, JS throws an error: Cannot read property 'push' of undefined . I read few threads about how to push elements/values to an array in Angular, but no one seems to have the exact same problem.

Here's my code:

function TestController($mdDialog, $scope, $mdSidenav, $mdBottomSheet, $timeout, $log) {
    $scope.questionSet = [];
    $scope.question = {
        text: null,
        answers: [],
        correctIndex: -1
    };

    $scope.clickPoP = function(ev) {
        // Appending dialog to document.body to cover sidenav in docs app
        // Modal dialogs should fully cover application
        // to prevent interaction outside of dialog
        var parentEl = angular.element(document.body);

        $mdDialog.show({
            parent: parentEl,
            targetEvent: ev,
            templateUrl: "edit-word-dialog.tmpl.html",
            locals: {
                items: $scope.question
            },
            controller: DialogController
        });

        function DialogController($scope, $mdDialog) {
            $scope.cancel = function() {
                $mdDialog.hide();
            }

            $scope.addQuestion = function(nextQuestion) {
                if (nextQuestion === true) {
                    console.log($scope.question);
                    $scope.questionSet.push($scope.question);
                    console.log('added question - clearing object - waiting for next input');
                } else {
                    console.log($scope.questionSet);
                    console.log('added question - closing dialog box');
                    $mdDialog.hide();
                }
            }

            $scope.setAnswer = function(index) {
                $scope.question.correctIndex = index;
                console.log(index);
            }
        }
    };
}

As you can see questionSet is supposed to hold the questions, and is defined and initialised at the start of the controller.

Then in the addQuestion() function i try to push my JSON object, which has all the correct data inside, into the questionSet , and thats where the error is thrown.

I have checked all my data, all data-binding and it all is correct, It just wont push the JSON into the array. Please note, that I would like to rather avoid appending to the array, to make it simpler to manage. Please also note that I am quite new to Angular.

Thank you for all the help, and apologies for the long read.

Here's the code for the dialog box, in case the error lies there:

<md-dialog class="email-dialog" flex="80" flex-sm="100">
<md-toolbar class="toolbar-default" md-theme="{{triSkin.elements.toolbar}}" palette-background="myPurple:500">
    <div class="md-toolbar-tools">
        <h2>
          <span>Quiz</span>
        </h2>
        <span flex></span>
    </div>
</md-toolbar>
<md-divider></md-divider>
<md-dialog-content class="sticky-container">
    <div>
        <md-content>
            <md-input-container>
                <label for="question-text">Enter Question</label>
                <input type="text" id="quiz-question" label="quiz-question" name="quiz-question" ng-model="question.text">
            </md-input-container>
            <div style="float: right; width: 10%">
                <md-radio-group>
                    <md-radio-button value="0" aria-label="ans0" ng-click="setAnswer(0)"></md-radio-button>
                    <br/>
                    <br/>
                    <md-radio-button value="1" aria-label="ans1" ng-click="setAnswer(1)"></md-radio-button>
                    <br/>
                    <br/>
                    <md-radio-button value="2" aria-label="ans2" ng-click="setAnswer(2)"></md-radio-button>
                    <br/>
                    <br/>
                    <md-radio-button value="3" aria-label="ans3" ng-click="setAnswer(3)"></md-radio-button>
                </md-radio-group>
            </div>
            <div style="float: right; width: 80%;">
                <md-input-container>
                    <label for="answer-one">Enter answer</label>
                    <input type="text" id="quiz-answer-one" label="quiz-answer-one" name="quiz-answer-one" ng-model="question.answers[0]">
                </md-input-container>
                <md-input-container>
                    <label for="answer-two">Enter answer</label>
                    <input type="text" id="quiz-answer-two" label="quiz-answer-two" name="quiz-answer-two" ng-model="question.answers[1]">
                </md-input-container>
                <md-input-container>
                    <label for="answer-three">Enter answer</label>
                    <input type="text" id="quiz-answer-three" label="quiz-answer-three" name="quiz-answer-three" ng-model="question.answers[2]">
                </md-input-container>
                <md-input-container>
                    <label for="answer-four">Enter answer</label>
                    <input type="text" id="quiz-answer-four" label="quiz-answer-four" name="quiz-answer-four" ng-model="question.answers[3]">
                </md-input-container>
            </div>
            <div style="float:left;">
                <md-button class="md-primary" aria-label="AddQuestion" ng-click="addQuestion(true)">Add Question</md-button>
                &nbsp;
                <md-button class="md-secondary" aria-label="Save" ng-click="addQuestion(false)">Save</md-button>
            </div>
        </md-content>
    </div>
</md-dialog-content>
<div class="md-actions" layout="row">
    <span flex></span>
    <md-button class="md-primary" aria-label="Close" ng-click="cancel()">
        Close
    </md-button>
</div>

You define $scope.questionSet in your parent controller, not in the dialogcontroller.

MdDialog uses the isolated scope by default. You could use the parent controller scope by passing scope: $scope in the $mdDialog call in TestController.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM