繁体   English   中英

控制器$ scope变量更改时,AngularJS视图不更新?

[英]AngularJS View not updating when Controllers $scope variables changed?

基本上,我的问题是我有一个AngularJS视图(home.html),该视图在双括号中包含一个变量,如下所示:{{message}}

修改$ scope.message变量后,带有的视图不会更新,尽管应该更新? 我尝试添加$ scope。$ apply()导致“执行中的操作”行异常

检查下面的代码。 即使在MainCtrl中将$ scope.message设置为新值时,在MainCtrl中调用$ scope.doLogin时,home.html中的{{message}}部分也不会更新。

非常感谢您的帮助,如果需要任何其他信息,请询问。

的index.html

<!DOCTYPE html>

<html ng-app="myApp">
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <link href="stylesheet.css" rel="stylesheet">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
    <base href="/">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
    <script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>

</head>
<body>

    <div ng-controller="MainCtrl">
        <nav class="navbar navbar-default">
            <div class="container">
                <div class="navbar-header">
                    <a class="navbar-brand" href="#">TriviaAttack</a>
                </div>
                <div id="navbar" class="navbar-collapse collapse">
                    <form id="loginForm" class="navbar-form navbar-right">
                        <div class="form-group">
                            <input type="text" placeholder="Email" class="form-control" ng-model="loginData.username">
                        </div>
                        <div class="form-group">
                            <input type="text" placeholder="Password" class="form-control" ng-model="loginData.password">
                        </div>
                        <div class="form-group">
                            <button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
                        </div>                  
                    </form>
                </div>
            </div>
        </nav>
    </div>

    <div ng-view>

    </div>
    </div>

    <script src="./app/app.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">

</body>
</html>

home.html的

<div>
    <h1>Welcome to the Home Page</h1>
    <p>{{message}}</p>
</div>

app.js

var myApp = angular.module('myApp',['ngRoute', 'ngStorage']);

myApp.controller('MainCtrl', ['$rootScope', '$scope', '$location', 
    function($rootScope, $scope, $location) {

    $scope.message = 'testing message';

    $scope.loginData = {
        username: '',
        password: '',
        loggedIn: false
    }

    $scope.doLogin = function() {

        $scope.message = 'message changed!';
        $scope.$apply();

        Auth.doLogin($scope.loginData.username, $scope.loginData.password)
        .success(function(data) {
            if (data.success) {
                AuthToken.setToken(data.token);
                $location.path('/home');
                console.log($scope.loginData.loggedIn);
            }
        });

        $scope.loginData = {};
    }

}]);

//Middleware for all requests which adds the users token to the HTTP header.
myApp.factory('TokenInterceptor', ['$q', '$location', '$localStorage',
    function($q, $location, $localStorage) {

    //On each request, check if the user is logged in with a valid token.
    var interceptor = {
        request: function(config) {

            config.headers['X-Authorization-Token'] = $localStorage.token;
            return config;

        },
        responseError: function(response) {
            if(response.status === 401 || response.status === 403) {
                $location.path('/login');
            }
            return $q.reject(response);
        }
    };
    return interceptor;
}]);

myApp.config(['$routeProvider','$locationProvider','$httpProvider',
    function($routeProvider, $locationProvider, $httpProvider) {

        $routeProvider.
            when('/', {
                templateUrl: './app/views/landingpage.html',
                controller: 'MainCtrl'
            }).
            when('/home', {
                templateUrl: './app/views/home.html',
                controller: 'MainCtrl'
            }).
            otherwise({
                redirectTo: '/'
            });


        $locationProvider.html5Mode(true);

        $httpProvider.interceptors.push('TokenInterceptor');

    }

]);

console.log('app.js loaded!');

每次加载视图时,都会执行具有新作用域的控制器代码,因此不会反映新消息。 因此,流程类似于执行$ scope.doLogin时着陆页的控制器,即MainCtrl及其作用域,它将$ scope.message变量更改为“ Message Changed”,并将位置更改为home,则将MainCtrl分配给具有新作用域的主页它将继续执行MainCtrl的第一行,即

  $scope.message = 'testing message';

当您决定对登录页面和主页使用通用控制器时

尝试删除中的控制器选项

when('/', {
  templateUrl: './app/views/landingpage.html',
  controller: 'MainCtrl'
}).
when('/home', {
  templateUrl: './app/views/home.html',
  controller: 'MainCtrl'
}) 

并在中分配控制器

<div ng-controller="MainCtrl">
    <!--omitted-->
    <div ng-view></div>
</div>

否则,其他选择将是传递参数或使用ui-router,其中嵌套视图将自动从父控制器继承而无需重新运行控制器逻辑。

问题在于控制器的覆盖范围

<div ng-controller="MainCtrl">
    <!--omitted-->
</div>
<div ng-view></div>

$ scope.messageMainCtrl紧密相关,因此当填充ng-view时,除了具有MainCtrl ,但实际上它在该div之外,因此看不到该变量以使其起作用,请插入ng -查看MainCtrl div,如下所示

<div ng-controller="MainCtrl">
    <!--omitted-->
    <div ng-view></div>
</div>

但这是实际的问题

您倾向于使用ng-route,但没有任何路由配置,除非您配置routeProvider,否则ng-view永远不会填充home.html ,首先,制作一些此处所述的路由,执行表单操作,重定向到页面并相应地填充视图,它应该可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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