重新解析角度路径数据并保持数据同步

时间:2015-01-12 23:52:09

标签: javascript angularjs angular-ui-router angular-promise

我正在构建一个角度应用程序,它在表格中重复一组项目,并具有直接在表格内部编辑它们的功能。数据从HTTP API获取,该API由进行调用的服务处理,并将数据传递到注入的任何位置。

问题是当项目被修改时,我想重新运行当前路由的解析函数并更新项目集。但是,当我这样做时,新更新的数据确实是从API中获取的,但未在视图中更新。我怀疑我没有丢失对原始数组的引用。

目前我们正在通过在更新项目时使用$state.reload()解决此问题,这会重新初始化控制器,从而重置当前分页页面和/或名称搜索字段等内容。

我的配置和控制器的简化版本如下:

angular.module('myModule', ['ui.router']).config(function($stateProvider) {
  $stateProvider.state('dashboard.itemList', {
    url: '/items',
    controller: 'fooController',
    resolve: {
      items: ['$q', 'dataService', 'spinner', function($q, dataService, spinner) {
        return $q(function(resolve, reject) {
          spinner.start();

          // Resolves an array of objects from the server
          dataService.getItems().then(function(allItems) {
            spinner.stop();
            resolve(allItems);
          }, function(error) {
            spinner.stop();
            reject(error);
          });
        });
      }]
    }
  })
});

angular.module('myModule').controller('fooController', function($scope, $state, $stateParams, items) {
  $scope.items = items;
  $scope.inlineEdit = function(item) {
    // Call the PUT-method on the API to modify an item
    apiService.update(item).then(function() {
      // Reload the data on successful update
      $state.transitionTo($state.current, $stateParams, {
        reload: true,
        inherit: false,
        notify: false
      });
    });
  }
});

我走错了路吗?对我的案子来说,这是更好的解决方案吗?

3 个答案:

答案 0 :(得分:0)

也许试试这个?我已经将退货声明添加到您的解决方案并拒绝方案,并采用了我首选的解决方案:

angular.module('myModule', ['ui.router']).config(function($stateProvider) {
  $stateProvider.state('dashboard.itemList', {
    url: '/items',
    controller: 'fooController',
    resolve: {
      items: ['$q', 'dataService', 'spinner', function($q, dataService, spinner) {
        spinner.start();
        // Resolves an array of objects from the server
        return dataService.getItems().then(function(allItems) {
            spinner.stop();
            return $q.resolve(allItems);
        }, function(error) {
            spinner.stop();
            return $q.reject(error);
        });
      }]
    }
  })
});

angular.module('myModule').controller('fooController', function($scope, $state, $stateParams, items) {
  $scope.items = items;
  $scope.inlineEdit = function(item) {
    // Call the PUT-method on the API to modify an item
    $q.when(apiService.update(item)).then(function() {
      // Reload the data on successful update
      $state.transitionTo($state.current, $stateParams, {
        reload: true,
        inherit: false,
        notify: false
      });
    });
  }
});

希望它有所帮助!

答案 1 :(得分:0)

您可能想尝试将返回包装到自己的函数中。这将阻止对$q对象的任何缓存。

resolve: {
  items: function() {
    return invokeTheQStuff() 
  }
}

答案 2 :(得分:0)

通过将获取的数组存储在dataService中的变量中来解决它,该变量在获取新数据时使用angular.copy方法重新填充。在服务中传递对该数组的单独引用,该引用现在始终同步!

angular.module('myModule', ['ui.router']).config(function($stateProvider) {
  $stateProvider.state('dashboard.itemList', {
    url: '/items',
    controller: 'fooController',
    resolve: {
      items: ['$q', 'dataService', 'spinner', function($q, dataService, spinner) {
        return $q(function(resolve, reject) {
          spinner.start();

          // Resolves an array of objects from the server
          dataService.getItems().then(function() {
            spinner.stop();
            resolve(dataService.items);
          }, function(error) {
            spinner.stop();
            reject(error);
          });
        });
      }]
    }
  })
});

angular.module('myModule').controller('fooController', function($scope, items, spinner) {
  $scope.items = items;
  $scope.inlineEdit = function(item) {
    // Call the PUT-method on the API to modify an item
    spinner.start();
    apiService.update(item).then(function() {
      spinner.stop();
    });
  }
});

angular.module('myModule').service('dataService', function(apiService) {
  var items = [];
  var getItems = function() {
    apiService.get('items').then(function(itemsFromApi) {
      // Instead of resolving a promise with the result, im just setting the items array here instead
      items = angular.copy(itemsFromApi, items);
    })
  };

  return {
    getItems: getItems,
    items: items
  };
});