2015-09-07 88 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

相關問題