最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngularJS Bind service array variable to controller scope - Stack Overflow

programmeradmin0浏览0评论

I have been able to properly bind an object with primitive data from a service to a scope variable from a controller but I'm having trouble doing the same thing with an array variable from the service.

service.js

myServices.factory('MyService', ['$http', function($http) {
var mySets = [];

  return {
  initMySets: function(userId, success, error) {
    $http.get(apiUrl + "/controller/getmysets", {params:{id:userId}}).success(function (data) {
      mySets = [];
      angular.copy(data, mySets);
    }).error(error);
  },

  getMySets: mySets


}]);

controllers.js

myControllers.controller('MenuController', ['$scope', 'UserService', 'MyService',
  function ($scope, UserService, MyService) {

  $scope.user = UserService.user;
  $scope.mySets = MyService.getMySets;

  $scope.logout = function() {
    UserService.logout();
  }
}]);

index.html

<nav id="app-menu"  ng-controller="MenuController" ng-class="{hide:!global.showMenu,slide:global.showMenu}">
  <div id="menu-head">
    <h4>{{user.Email}}</h4>
  </div>
  <ul>
    <div ng-switch on="user.UserId != null">
      <li ng-switch-when="true"><a href="#/main" ng-click="toggleMenu();logout();">Logout</a></li>
      <li ng-switch-when="false"><a href="#/login" ng-click="toggleMenu()">Login</a></li>
      <li ng-switch-when="true" ng-repeat="mySet in mySets">
        <a href="#/mySet /{{mySet.MySetId}}" ng-click="toggleMenu()">{{mySet.Label}}</a>
      </li>
    </div>
  </ul>
</nav>

I have a login function that calls initMySets on success passing in the userId and I know that the mySets variable in the service is getting populated properly on the angular copy but I'm not getting the actual update in the controller.

The $scope.user variable is being updated from the UserService, but the mySet ng-repeat isn't displaying the list from the service.

The data being returned from the http.get is an IEnumerable collection of complex objects from my MVC Web API controller. I'm not sure if that makes a difference.

I have been able to properly bind an object with primitive data from a service to a scope variable from a controller but I'm having trouble doing the same thing with an array variable from the service.

service.js

myServices.factory('MyService', ['$http', function($http) {
var mySets = [];

  return {
  initMySets: function(userId, success, error) {
    $http.get(apiUrl + "/controller/getmysets", {params:{id:userId}}).success(function (data) {
      mySets = [];
      angular.copy(data, mySets);
    }).error(error);
  },

  getMySets: mySets


}]);

controllers.js

myControllers.controller('MenuController', ['$scope', 'UserService', 'MyService',
  function ($scope, UserService, MyService) {

  $scope.user = UserService.user;
  $scope.mySets = MyService.getMySets;

  $scope.logout = function() {
    UserService.logout();
  }
}]);

index.html

<nav id="app-menu"  ng-controller="MenuController" ng-class="{hide:!global.showMenu,slide:global.showMenu}">
  <div id="menu-head">
    <h4>{{user.Email}}</h4>
  </div>
  <ul>
    <div ng-switch on="user.UserId != null">
      <li ng-switch-when="true"><a href="#/main" ng-click="toggleMenu();logout();">Logout</a></li>
      <li ng-switch-when="false"><a href="#/login" ng-click="toggleMenu()">Login</a></li>
      <li ng-switch-when="true" ng-repeat="mySet in mySets">
        <a href="#/mySet /{{mySet.MySetId}}" ng-click="toggleMenu()">{{mySet.Label}}</a>
      </li>
    </div>
  </ul>
</nav>

I have a login function that calls initMySets on success passing in the userId and I know that the mySets variable in the service is getting populated properly on the angular copy but I'm not getting the actual update in the controller.

The $scope.user variable is being updated from the UserService, but the mySet ng-repeat isn't displaying the list from the service.

The data being returned from the http.get is an IEnumerable collection of complex objects from my MVC Web API controller. I'm not sure if that makes a difference.

Share Improve this question asked Jan 7, 2014 at 8:18 joshua.johnson.814joshua.johnson.814 1331 gold badge1 silver badge7 bronze badges 2
  • 1 Take a look at $apply() method: docs.angularjs.org/api/ng.$rootScope.Scope – Ivan Chernykh Commented Jan 7, 2014 at 8:28
  • @Cherniv whilst $apply does force an update and may be useful to some, services themselves don't have scopes and calling this method on the $rootScope can be expensive. – Blowsie Commented Jan 26, 2016 at 8:13
Add a comment  | 

2 Answers 2

Reset to default 16

Binding does not work because your array (in your controller) never change.

When your initSets success function is called, your internal array points to a new array but your scope variable still points to your empty initial array.

Instead of create a new array, clear your initial array and push new items to initial array:

Replace that:

mySets = [];
angular.copy(data, mySets);

By that:

mySets.length = 0; // Clear initial array
mySets.push.apply(mySets, data); // Push data to initial array

See this fiddle (I simulate an asynchronous callback using $timeout) : http://jsfiddle.net/UJTPD

Instead of assigning a new list (mySets = []) and then calling angular.copy, you should just be calling angular.copy;

Like this;

angular.copy(data, mySets);
发布评论

评论列表(0)

  1. 暂无评论