Параметр в функции контроллера возвращает неопределенный ReferenceError

0

Я прохожу через эту учебную лабораторию для AngularJS. Я могу заставить пример работать как есть (с незначительным исправлением ошибок).

Я также пытаюсь изучить некоторые хорошие методы кодирования, касающиеся AngluarJS, ссылаясь на это руководство. Это привело к созданию js файла, который выглядит так:

(function () {
'use strict';

angular.module('QuizApp', []);

angular.module('QuizApp').controller('QuizCtrl', QuizController);

function QuizController($http) {
    var vm = this;

    vm.answer = answer();
    vm.answered = false;
    vm.correctAnswer = false;
    vm.nextQuestion = nextQuestion();
    vm.options = [];
    vm.sendAnswer = sendAnswer(option);
    vm.title = "loading question...";
    vm.working = false;

    function answer() {
        return vm.correctAnswer ? 'correct' : 'incorrect';
    }

    function nextQuestion() {
        vm.working = true;
        vm.answered = false;
        vm.title = "loading question...";
        vm.options = [];

        $http.get("/api/trivia")
        .success(function (data, status, headers, config) {
            vm.options = data.options;
            vm.title = data.title;
            vm.answered = false;
            vm.working = false;
        }).error(function (data, status, headers, config) {
            vm.title = "Oops... something went wrong.";
            vm.working = false;
        });
    }

    function sendAnswer(option) {
        vm.working = true;
        vm.answered = true;

        $http.post('/api/trivia', { 'questionId': option.questionId, 'optionId': option.id })
        .success(function (data, status, headers, config) {
            vm.correctAnswer = (data === true);
            vm.working = false;
        })
        .error(function (data, status, headers, config) {
            vm.title = "Oops... something went wrong.";
            vm.working = false;
        });
    }
};
})();

Однако этот код вызывает следующую ошибку при загрузке страницы.

ReferenceError: опция "option" не определена в QuizController (http://localhost: 17640/Scripts/app/quiz-controller.js: 16: 9) при вызове (http://localhost: 17640/Scripts/angular.js: 4473: 7) в функции Anonymous (http://localhost: 17640/Scripts/angular.js: 9093: 11) в nodeLinkFn (http://localhost: 17640/Scripts/angular.js: 8205: 13) на составномLinkFn (http ://localhost: 17640/Scripts/angular.js: 7637: 13) в составнойLinkFn (http://localhost: 17640/Scripts/angular.js: 7641:13) в составнойLinkFn (http://localhost: 17640/Scripts/angular.js:7641:13) в составнойLinkFn (http://localhost: 17640/Scripts/angular.js: 7641:13) в составномLinkFn (http://localhost: 17640/Scripts/angular.js: 7641:13) в publicLinkFn (http://localhost: 17640/Scripts/angular.js: 7512: 30)

По какой-то причине он, похоже, пытается немедленно выполнить sendAnswer. Поскольку он не работает, javascript останавливается на середине страницы, отображая угловое имя свойства {{title}} на странице вместо того, чтобы задавать вопрос на странице. Я пробовал разные способы определения и вызова vm.sendAnswer и function sendAnswer, без везения.

Для справки, вот код для моего представления (обратите внимание на ng-repeat on options - этот код представления отлично работает, когда он точно соответствует лабораторному упражнению):

<div id="bodyContainer" ng-app="QuizApp">
<section id="content">
    <div class="container">
        <div class="row">
            <div class="flip-container text-center col-md-12" ng-controller="QuizCtrl" ng-init="nextQuestion()">
                <div class="back" ng-class="{flip: answered, correct: correctAnswer, incorrect:!correctAnswer}">
                    <p class="lead">{{answer()}}</p>
                    <p>
                        <button class="btn btn-info btn-lg next option" ng-click="nextQuestion()" ng-disabled="working">Next Question</button>
                    </p>
                </div>
                <div class="front" ng-class="{flip: answered}">
                    <p class="lead">{{title}}</p>
                    <div class="row text-center">
                        <button class="btn btn-info btn-lg option" ng-repeat="option in options" ng-click="sendAnswer(option)" ng-disabled="working">{{option.title}}</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>
</div>

Как я могу сохранить свою практику кодирования (по существу, избегать использования $scope в этой ситуации и объявить все мои свойства viewmodel в верхней части контроллера), но заставить функцию работать правильно?

Теги:
asp.net-mvc

2 ответа

0
Лучший ответ

У меня есть этот пример, работающий сейчас.

Для начала, свойства контроллера, которые подключены к функциям, просто должны ссылаться на имена функций.

vm.answer = answer;
vm.nextQuestion = nextQuestion;
vm.sendAnswer = sendAnswer;

Тогда нам нужен псевдоним для нашего контроллера на нашем представлении, чтобы мы могли легче ссылаться на него.

<div class="flip-container text-center col-md-12" ng-controller="QuizCtrl as quiz" ng-init="quiz.nextQuestion()">
    <div class="back" ng-class="{flip: quiz.answered, correct: quiz.correctAnswer, incorrect:!quiz.correctAnswer}">
        <p class="lead">{{quiz.answer()}}</p>
        <p>
            <button class="btn btn-info btn-lg next option" ng-click="quiz.nextQuestion()" ng-disabled="quiz.working">Next Question</button>
        </p>
    </div>
    <div class="front" ng-class="{flip: quiz.answered}">
        <p class="lead">{{quiz.title}}</p>
        <div class="row text-center">
            <button class="btn btn-info btn-lg option" ng-repeat="option in quiz.options" ng-click="quiz.sendAnswer(option)" ng-disabled="quiz.working">{{option.title}}</button>
        </div>
    </div>
</div>

И это в значительной степени. Просто очистите определения свойств в угловом контроллере, а затем используйте псевдоним для контроллера на представлении. Все остальное - это почти тот же код, что и в вопросе.

Вот полный код сейчас. Угловой контроллер:

(function () {
'use strict';

angular.module('QuizApp', []);

angular.module('QuizApp').controller('QuizCtrl', QuizController);

function QuizController($http) {
    var vm = this;

    vm.answer = answer;
    vm.answered = false;
    vm.correctAnswer = false;
    vm.nextQuestion = nextQuestion;
    vm.options = [];
    vm.sendAnswer = sendAnswer;
    vm.title = "loading question...";
    vm.working = false;

    function answer() {
        return vm.correctAnswer ? 'correct' : 'incorrect';
    };

    function nextQuestion() {
        vm.working = true;
        vm.answered = false;
        vm.title = "loading question...";
        vm.options = [];

        $http.get("/api/trivia")
        .success(function (data, status, headers, config) {

            var answerOptions = data.options;

            while (answerOptions.length > 0){
                var random = Math.floor(Math.random() * answerOptions.length, 0);
                alert(random);

                vm.options.push(answerOptions[random]);
                answerOptions.splice(random, 1);
            }

            //vm.options = data.options;
            vm.title = data.title;
            vm.answered = false;
            vm.working = false;
        }).error(function (data, status, headers, config) {
            vm.title = "Oops... something went wrong.";
            vm.working = false;
        });
    };

    function sendAnswer(option)
    {
        vm.working = true;
        vm.answered = true;

        $http.post('/api/trivia', { 'questionId': option.questionId, 'optionId': option.id }).success(function (data, status, headers, config) {
            vm.correctAnswer = (data === true);
        }).error(function (data, status, headers, config) {
            vm.title = "Oops... something went wrong";                
        });

        vm.working = false;
    }
};
})();

Просмотр MVC:

@{
    ViewBag.Title = "Play";
}

<div id="bodyContainer" ng-app="QuizApp">
    <section id="content">
        <div class="container">
            <div class="row">
                <div class="flip-container text-center col-md-12" ng-controller="QuizCtrl as quiz" ng-init="quiz.nextQuestion()">
                    <div class="back" ng-class="{flip: quiz.answered, correct: quiz.correctAnswer, incorrect:!quiz.correctAnswer}">
                        <p class="lead">{{quiz.answer()}}</p>
                        <p>
                            <button class="btn btn-info btn-lg next option" ng-click="quiz.nextQuestion()" ng-disabled="quiz.working">Next Question</button>
                        </p>
                    </div>
                    <div class="front" ng-class="{flip: quiz.answered}">
                        <p class="lead">{{quiz.title}}</p>
                        <div class="row text-center">
                            <button class="btn btn-info btn-lg option" ng-repeat="option in quiz.options" ng-click="quiz.sendAnswer(option)" ng-disabled="quiz.working">{{option.title}}</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
</div>

@section scripts {
    @Scripts.Render("~/Scripts/angular.js")
    @Scripts.Render("~/Scripts/app/quiz-controller.js")
}
0

Вы планируете отправить vm.options = []; vm.sendAnswer = sendAnswer(option); vm.options = []; vm.sendAnswer = sendAnswer(option);

vm.options в функцию sendAnswer(), потому что option не определена. вы не получите ошибку, если вы вложите "параметр" в строку и передаете ее в функцию. Но тогда вы не получите желаемого объекта. добавьте это где-нибудь в верхнюю var option = {}.

  • 0
    Я спешил уйти и не опубликовал свою точку зрения. В представлении options есть ng-repeat, которое разбивает их на несколько option . Тогда есть ng-щелчок для sendAnswer(option) .
  • 0
    vm.sendAnswer твоя функция все равно будет работать правильно. Также вы не можете получить доступ к данным option из его функции sendAnswer() за исключением того, что вы передаете ответ об успешном выполнении в другую функцию.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню