admin管理员组

文章数量:1332339

basically my issue is that I have a AngularJS view (home.html) which contains a variable in double brackets like so: {{message}}

When the $scope.message variable is modified, the view with does not update, although it should? I have tried adding $scope.$apply() which results in an exception along the lines of 'Action in Progress'

Check my code below. The {{message}} part in home.html is not being updated when $scope.doLogin is called in MainCtrl, even though I have set $scope.message to a new value in that function.

Any help is greatly appreciated and if any further info is needed, please ask.

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=".3.5/css/bootstrap.min.css" rel="stylesheet">
    <link href="stylesheet.css" rel="stylesheet">

    <script src=".11.3/jquery.min.js"></script>

    <script src=".js/1.4.4/angular.min.js"></script>
    <script src=".js/1.4.4/angular-route.min.js"></script>
    <base href="/">

    <script src=".3.9/ngStorage.js"></script>
    <script src=".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=".3.5/js/bootstrap.min.js">

</body>
</html>

home.html

<div>
    <h1>Wele 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!');

basically my issue is that I have a AngularJS view (home.html) which contains a variable in double brackets like so: {{message}}

When the $scope.message variable is modified, the view with does not update, although it should? I have tried adding $scope.$apply() which results in an exception along the lines of 'Action in Progress'

Check my code below. The {{message}} part in home.html is not being updated when $scope.doLogin is called in MainCtrl, even though I have set $scope.message to a new value in that function.

Any help is greatly appreciated and if any further info is needed, please ask.

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./bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
    <link href="stylesheet.css" rel="stylesheet">

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

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

    <script src="https://cdnjs.cloudflare./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./bootstrap/3.3.5/js/bootstrap.min.js">

</body>
</html>

home.html

<div>
    <h1>Wele 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!');
Share Improve this question asked Sep 7, 2015 at 5:26 JohnWickJohnWick 5,1499 gold badges40 silver badges79 bronze badges 4
  • All your views are using their own MainCtrl and have their own $scope so when you call doLogin from the the login form it will only update the message in it's own scope, not the controller of the ng-view. – logee Commented Sep 7, 2015 at 5:35
  • Hi, so what I am trying to do is not possible? Or what is your suggested solution. I appreciate your response btw thank you :) – JohnWick Commented Sep 7, 2015 at 5:49
  • See Angular: Share data between controllers. In a nutshell, return an object from a factory and work off that in the controllers. Let us know if it doesn't help. – logee Commented Sep 7, 2015 at 5:55
  • Thanks for the link. I will change my code a bit and implement the pattern and let you know if it works. – JohnWick Commented Sep 7, 2015 at 5:56
Add a ment  | 

2 Answers 2

Reset to default 2

Each time a view is loaded ,the controller code with new scope executes so the new message is not reflected. So the flow be like landingPage's controller which is MainCtrl with its scope when $scope.doLogin is executed will change the $scope.message variable to "Message Changed" and upon changing location to home , the MainCtrl is assigned to home page with new scope which would continue executing the very first line of MainCtrl i.e.

  $scope.message = 'testing message';

As you have decided to use mon controller for login and home pages

Try removing controller option in

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

And assign controller in

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

Or else other options would be to pass parameters or use ui-router wherein nested views would automatically inherit from parent controllers without rerunning the controller logic.

Problem is in controller coverage

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

Your $scope.message is tight to your MainCtrl, so when ng-view is populated, you except that it has MainCtrl, but indeed it's outside of that div, so just doesn't see that variable, to make it work, insert ng-view to MainCtrl div like shown below

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

But here's the actual problem

You tend to use ng-route but you don't have any route configurations, ng-view will never be populated with home.html unless you configure you routeProvider, first of all, make some routes like described here, perform your form action, redirect to page and populate views accordingly, it should work.

本文标签: javascriptAngularJS View not updating when Controllers scope variables changedStack Overflow