2013-07-02 38 views
1

我想構建一個簡單的用戶名登錄系統。這只是爲了記錄我可以在我的各種控制器中使用的用戶名。爲什麼在控制器間共享數據在AngularJS中不起作用

但是,出於某種原因,我無法在abcController

這個問題的實質是在控制器之間共享數據得到$scope.userName值。

controller.js

app.controller('userNameController',function ($scope, $log, Config, Session) 
{ 
    Session.updateSession($scope.userName); 
}); 

app.controller('abcController',function ($scope, $log, Config, Session) 
{ 
    $scope.userName=Session.data.username; 
    //some other code 
}); 

resource.js

app.factory('Session', function() { 
    var Session = { 
     data: {}, 
     updateSession: function(userName) { 
      Session.data = { "username": userName } 
     } 
    }; 
    return Session; 
}); 

只要用戶點擊登錄按鈕Twitter的引導模式(彈出)將出現,並詢問用戶輸入他們的用戶名。

的index.html

<div ng-controller="userNameController"> 
<button class="btn" id="enterUsernameBtn" href="#userNameModal" role="button" class="btn" data-toggle="modal" title="Enter Username">Login</button> 
</div> 

    <!-- UserName Modal --> 
    <div id="userNameModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="userNameModalLabel" aria-hidden="true"> 
     <div class="modal-header"> 
      <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> 
      <h3 id="userNameModalLabel">Enter your username</h3> 
     </div> 
     <div class="modal-body"> 
      <p><b>UserId</b></p> 
      <div class="input-append"> 
       <input class="pull-left" id="userIdTextBox" type="text" style="left:8px; width:160px" ng-controller="userNameController" ng-model="userName"> 
      </div> 
     </div> 
     <div class="modal-footer"> 
      <button class="btn" data-dismiss="modal" aria-hidden="true">Submit</button> 
     </div> 
    </div> 

請隨時提出,如果有更好的方法做什麼,我想上面做。

+0

這不是因爲你的abcController已經由時間運行userNameController套userName屬性?推測$ scope.userName ===在abcController中未定義。如果您在需要時直接使用Session.data.username會發生什麼情況?您可能需要將會話資源附加到您的abcController $ scope。 – cirrus

+0

你可能會發現這篇文章很有趣http://blog.jdriven.com/2013/03/how-to-create-singleton-angularjs-services-in-4-different-ways/ – vittore

+0

@cirrus,你是對的。這可能會發生。我寫了'app.run(function(Session){}); // bootstrap session;'在其他任何.js文件之前引用的app.js中。這沒有幫助。我沒有將Session資源附加到abcController嗎?請幫助,angularJS noob在這裏。 – Watt

回答

3

如果你像這樣定義你的資源有幫助嗎?

app.factory('Session', function() { 
    var Session = { 
     data: { username: undefined }, // ensure object ref to attach to 
     updateSession: function(userName) { 
      Session.data.username = userName; // do NOT recreate the object above 
     } 
    }; 
    return Session; 
}); 

我認爲可能發生的情況(我不能看到所有的代碼),但我不認爲當你在abcController參考username設置。通過首先定義abcController可以附加到的對象模式中的共享引用,它將在稍後調用updateSession()時反映更改。

這是一個工作example使用你的服務理念。

+1

我在某處讀過,應該寫'app.run(function(Session){}); // bootstrap session;'in'app.js'會有幫助嗎? – Watt

+0

順便說一句,我定義我的資源,因爲你建議,這並沒有幫助。 – Watt

+0

可以肯定的是,兩個控制器中的console.log()都可以看到訂單,並將用戶名設置爲初始虛擬值,稱爲「xxxx」。當你改變這個值時,你應該看到它反映在abcController中,但是記住你需要一個'。'參考。如果你改變底層參考,你會打破兩者之間的聯繫。在之前的代碼中,您完全使用了REASSIGNED數據,因此abcController綁定到了不同的數據對象,更不用提一個未定義的用戶名屬性。 – cirrus

0

我發現使用emitbroadcast的備用解決方案。在此jsfiddle

完整的代碼示例app.js

app.run(function($rootScope) { 
    /* 
    Receive emitted message and broadcast it. 
    Event names must be distinct or browser will blow up! 
    */ 
    $rootScope.$on('handleEmit', function(event, args) { 
     $rootScope.$broadcast('handleBroadcast', args); 
    }); 
}); 

controller.js

app.controller('userNameController',function ($scope, $log, Config) 
{ 

    $scope.submitUserName= function() 
    { 
     // Session.updateSession($scope.userName); 
     $scope.$emit('handleEmit', {username: $scope.userName}); 
    }; 

}); 

app.controller('abcController',function ($scope, $log, Config) 
{ 
    $scope.$on('handleBroadcast', function(event, args) { 
     $scope.userName = args.username; 
     }); 
    //some other code 
}); 
+0

其實,再想一想,這可能是你必須做的,因爲你的摘要循環不會在其他控制器中運行,否則。因此,除非在userNameController中發生某些事情時,在abcController中觸發摘要循環,否則即使*看到userName,也會看到更改。我的建議會通過你的服務傳播userName,但你需要一些其他的機制來觸發abcController的$摘要。 – cirrus

相關問題