javascript - AngularJS - 将 Controller 重构为服务 - 理解 self/this 和范围

标签 javascript angularjs

我是 AngularJS 的新手,我的 JavaScript 知识现在还不是那么强,所以我提前道歉,同时我戴着白腰带暴露了我的无知。

我在将以下 Controller 重构为服务时遇到了一些困难,主要是为了分离关注点并将逻辑进一步插入堆栈,并使我的控​​制器再次变得精简。

airBnbClone.controller('SpacesCtrl', ['$http', '$location', function( $http, $location) {
  var self = this;
  self.spaces = [];
  self.currentspace;

  self.create = function(space) {
    $http.post('http://localhost:3000/api/spaces', space).success(function(data) {
      self.spaces.push(data);
      self.showSpace(data.space);
    });
  };

  self.getSpaces = function(){
    $http.get('http://localhost:3000/api/spaces.json').then(function(response){
      self.spaces = response.data.reverse();
    });
  };

  self.showSpace = function(space){
    $http.get('http://localhost:3000/api/spaces/' + space.id).then(function(response){
      self.currentspace = response.data;
      $location.path('/spaces/' + space.id)
    });
  };
}]);

经过一些重构,我的代码现在看起来像这样:

airBnbClone.controller('SpacesCtrl', ['$http', '$location', 'spacesService', function( $http, $location, spacesService) {
  var self = this;

  self.create = function(space) {
    spacesService.createSpace(space);
  };

  self.getSpaces = function(){
    spacesService.getSpaces();
  };

  self.showSpace = function(space){
    spacesService.showSpace(space);
  };
}])
.service('spacesService', ['$http', '$location', function($http, $location){
  var self = this;
  self.spaces = [];
  self.currentspace;

  this.createSpace = function(space){
    $http.post('http://localhost:3000/api/spaces', space).success(function(data) {
      self.spaces.push(data);
      self.showSpace(data.space);
    });
  }

  this.getSpaces = function(){
    $http.get('http://localhost:3000/api/spaces.json').then(function(response){
      self.spaces = response.data.reverse();
    });
  };

  this.showSpace = function(space){
    $http.get('http://localhost:3000/api/spaces/' + space.id).then(function(response){
      self.currentspace = response.data;
      $location.path('/spaces/' + space.id)
    });
  };
}]);

而在重构之前,我的代码按预期运行。我的主视图有一个 ng-init='spacescontroller.getSpaces()',其中 my ng-controller='SpacesCtrl as spacecontroller' 拉入我的空间列表。当我单击特定空间时,它会按预期显示该特定空间。

现在,使用我的重构代码,我的默认 View 根本不显示任何内容,当我创建空间时,它似乎无法更新 Controller 中的原始 self.spaces 数组.

基本上,我不确定如何将这些方法重构为服务。我的 self.spaces 和 self.currentspace 对象应该保留在 Controller 中,还是成为注入(inject)服务的属性?在这种情况下,哪种存储状态的首选方法是,为什么?

既然我的代码不再渲染 View ,为什么会出现这种情况?如果我的问题相当循环,我深表歉意,我已经为此研究了好几天,尽管咨询了许多不同的来源,但我开始感到非常困惑。

最佳答案

考虑从您的服务中返回 promise 。

app.service('spacesService', function($http) {

    this.getSpaces = function(){
        var url = 'http://localhost:3000/api/spaces.json';
        var promise = $http.get(url)
            .then(function(response){
                //return for chaining
                return response.data.reverse();
        });
        return promise;
     });
});

返回 Promise 的优点之一是它们保留错误信息。

在你的 Controller 中:

airBnbClone.controller('SpacesCtrl', function($http, $location, spacesService) {
    var self = this;
    self.spaces = [];

    self.getSpaces = function() {
        var promise = spacesService.getSpaces();

        promise.then(function onFulfilled(spaces) {
            self.spaces = spaces;
        }).catch(function onRejected(response) {
            console.log(response.status);
        });
    };
};

有关使用 Promise 的优势的更多信息,请参阅 Why are Callbacks from Promise .then Methods an Anti-Pattern?.

关于javascript - AngularJS - 将 Controller 重构为服务 - 理解 self/this 和范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36119652/

相关文章:

javascript - 如何使用 Angular js 将对象添加到存储在本地存储中的数组中?

javascript - 从另一个 Controller 调用 Angular Controller

angularjs - 如何使用 AngularJS 在 Controller 中调用服务功能?

angularjs - 未知提供商 : ServiceProvider <- Service <- Controller

javascript - 预期响应包含一个对象,但在 Angular js 中出现数组错误

javascript - 根据两个选择框更新html视频,加载但不播放视频

javascript - 如何获取 Json 文档数组中数组的索引

javascript - 查找视频元素的缓冲百分比

javascript - 如何获取所有选中的复选框

javascript - jQuery 中奇怪的 json 错误