2015-09-07 90 views
2

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

当$ scope.message变量被修改时,不更新,虽然它应该?我已经尝试添加$ scope。$ apply(),导致沿着'正在进行的操作'的行发生异常

请检查下面的代码。在MainCtrl中调用$ scope.doLogin时,home.html中的{{message}}部分未被更新,即使我已将$ scope.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!'); 
+0

所有的视图都使用自己的'MainCtrl'并有自己的'$ scope',所以当你从登录表单调用'doLogin'时,它只会更新它自己范围内的'message',而不是控制器'ng-view'。 – user2718281

+0

嗨,所以我想要做的是不可能的?或者你建议的解决方案是什么。我感谢你的回应btw谢谢:) –

+0

请参阅[Angular:控制器之间共享数据](http://stackoverflow.com/questions/21919962/angular-share-data-between-controllers)。简而言之,从工厂返回一个对象并在控制器中处理该对象。让我们知道它是否没有帮助。 – user2718281

回答

1

问题是在控制器的覆盖

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

$ scope.message是紧你的MainCtrl,填充ng-view所以当你以外,它MainCtrl,但实际上它是该分区之外,所以才没有看到变量,使之正常工作,将NG-视图MainCtrl格状图所示

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

但这里有一个实际的问题

您倾向于使用NG-路线,但你没有任何路由配置,ng-view绝不会与home.html填充,除非你配置你routeProvider,首先,作出这样描述here部分航线,执行表单动作,重定向到页面并相应地填充视图,它应该工作。

+0

嗨,我做了改变,并通过ng-click(它改变了$ scope.message)调用doLogin(),但home.html中的{{message}}仍然没有更新。即使在你建议的内嵌嵌入ng-view div。 –

+0

@DavidStampher更新! –

+0

嗨,routeProvider已经在这个例子中:P /和/ home被路由到不同的视图,但是同一个控制器。 –

2

每次加载视图时,带有新范围的控制器代码都会执行,因此不会反映新消息。 所以流程就像 当执行$ scope.doLogin时,它的作用域为MainCtrl的landingPage的控制器会将$ 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其中在嵌套视图中会自动从父控制器继承而不重新运行控制器逻辑。

+0

嘿科迪我会玩弄这一点,看看它是否使我的工作方式,我也想。 –

+0

确定@DavidStampher请考虑接受它:P:P – NavyCody

相关问题