范围不会在另一个模板(AngularJS)中更新

时间:2015-02-05 00:23:58

标签: angularjs html5

我有两个模板。在这一个一切都很好,我的变量“得分”更新得很好:

HTML:

<div ng-controller="quizController">

<h1 id="question">{{currentQ.question}}</h1>
<div id="score">Score: {{score}}</div>

<ul class="answers">
    <li ng-repeat="option in currentQ.options">
        <a class="btn btn-primary" ng-click="answerClick($index)"><p>{{option}}</p></a>
    </li>
</ul>

<button class="prevBtn" ng-click="move(-1)"></button>
<button class="nextBtn" ng-click="move(1)"></button>

</div>

JS:

app.controller("quizController", function($scope, $http, $location){
$scope.score = 0;
$scope.clicks = 0;

$scope.move = function (direction) {

    if(direction > 0) {
        var position = $scope.allData.indexOf($scope.currentQ);
        $scope.currentQ = $scope.allData[position + direction];
    }
    else{
        return false;
    }
};

$http.get("js/json/questions.json").then(function(response){
    $scope.allData = response.data;
    $scope.currentQ = $scope.allData[0];
});

$scope.answerClick = function(index){
    $scope.clicks++;

    if($scope.clicks === 4){
        $location.path('/finish');
    }

    if(index === $scope.currentQ.answer){
        $scope.score++;
        $scope.move(+1);
    }
    else{
        $scope.move(+1);
    }
};

});

但是在此模板中,分数计数器不起作用:

HTML:

<div id="finish-score">Your Score: {{score}}</div>
<a class="btn btn-danger tryagainBtn" href="#/game"><p>Try again</p></a>

问题在于范围,但我不确切知道如何解决它。

2 个答案:

答案 0 :(得分:1)

根本原因是您对所有状态使用相同的控制器:root,game和finish。每次进入新状态时,控制器都将重新初始化为新视图。

您的代码的第一行是$scope.score = 0;,这就是为什么score在进入finish状态时始终为0的原因。修复此错误的正确方法是利用Angular服务(单身)来存储分数数据。

app.controller("quizController", function($scope, $http, $location, resultService){
    $scope.score = resultService.score;
    $scope.clicks = 0;

    $scope.move = function (direction) {

        if(direction > 0) {
            var position = $scope.allData.indexOf($scope.currentQ);
            $scope.currentQ = $scope.allData[position + direction];
        }
        else{
            return false;
        }
    };

    $http.get("questions.json").then(function(response){
        $scope.allData = response.data;
        $scope.currentQ = $scope.allData[0];
    });

    $scope.answerClick = function(index){
        $scope.clicks++;

        if($scope.clicks === 4){
            resultService.score = $scope.score;
            $location.path('/finish');
        }

        if(index === $scope.currentQ.answer){
            $scope.score++;
            $scope.move(+1);
        }
        else{
            $scope.move(+1);
        }
    };

});
app.service("resultService", function () {
  var resultService = { 
    score:0
  };
  return resultService;
});

我个人建议对不同的状态/视图使用不同的控制器,并继续使用服务进行数据存储/共享。您可以将功能分为homeControllerquizControllerresultController

的HomeController

app.controller("homeController", function($scope,){
    // currently we can do nothing in homeController
}

QuizController

app.controller("quizController", function($scope, $http, $location, resultService){
    // Same as legacy code
    $scope.score = resultService.score;
    ....
}

ResultController

app.controller("resultController", function($scope, $http, $location, resultService){
        $scope.score = resultService.score;
        $scope.tryAgain = function () {
          resultService.score = 0;
          $location.path('/game');
        }
}

此外,将路线改为

when('/', {
  templateUrl: '',
  controller: 'homeController' 
})
when('/game', {
  templateUrl: '',
  controller: 'quizController' 
}).
when('/finish', {
  templateUrl: '',
  controller: 'resultController'
}

因此,只有当用户访问'/#/ game'时才会加载quizController。

答案 1 :(得分:0)

$ scope中的scope与其他编程语言中的变量作用域相同。

您的变量$ scope.scores仅在控制器范围内可用,因此仅在使用ng-controller指令声明它的div标记内。

如果要在范围之外使其可用,可以使用$ rootscope声明全局变量的角度等效值。