2013-07-02 2 views
1

Я пытаюсь создать простую систему входа имени пользователя. Это просто запись имени пользователя, которое я могу использовать в разных контроллерах.Почему обмен данными между контроллерами не работает в AngularJS

Но, по некоторым причинам, я не могу получить $scope.userName значение в abcController

Суть этой проблемы обмена данными между контроллерами.

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; 
}); 

Как только пользователь нажимает на кнопку Войти щебетать-самозагрузки модальной (всплывающее окно) будет появляться и спрашивать пользователя для ввода имени пользователя.

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 === undefined в abcController. Что произойдет, если вы используете Session.data.username напрямую, когда вам это нужно? Возможно, вам потребуется подключить ресурс сеанса к вашей области аббревиатуры abcController. – 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; 'в app.js, на который ссылаются перед любыми другими .js-файлами. Это не помогло. Разве я не привязал ресурс сеанса к 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; 
}); 

Я думаю, что может происходить (и я не могу увидеть весь код), но я не думаю, что username устанавливается, когда вы берете ссылку в abcController. Определив общую ссылку в вашей схеме объектов, которую сначала можно подключить abcController, она будет отражать изменения позже, когда вызывается функция updateSession().

Работает example, используя вашу сервисную идею.

+1

Я где-то читал, должен писать 'app.run (function (Session) {}); // bootstrap session; 'в' app.js' поможет? – Watt

+0

Кстати, я определил свой ресурс, как вы предложили, что не помогло. – Watt

+0

Уверен, console.log() в обоих контроллерах, чтобы вы могли видеть порядок и задали имя пользователя для исходного фиктивного значения, например «xxxx». Когда вы меняете значение, вы должны увидеть его отражение в abcController, но помните, что вам нужно «.». Справка. Если вы * измените * базовую ссылку, вы нарушите связь между ними. В вашем предыдущем коде у вас были REASSIGNED данные полностью, поэтому abcController был привязан к DIFFERENT объекту {}, не говоря уже о неопределенном имени пользователя. – cirrus

0

Я нашел альтернативное решение, используя emit и broadcast. Полный пример кода в этой 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

На самом деле, думая снова, это, вероятно, то, что вам нужно будет сделать, потому что ваш цикл дайджеста не будет работать в других контроллерах в противном случае. Поэтому, если в abcController нет ничего, что могло бы вызвать цикл дайджеста, когда что-то происходит в userNameController, вы не увидите изменения в userName даже * if *, если бы увидели это, если бы это выглядело. Мое предложение будет получать userName, распространяемое через вашу службу, но вам понадобится другой механизм для запуска $ digest для abcController. – cirrus