繁体   English   中英

在控制器AngularJs与服务之间共享数据

[英]Share data between controllers AngularJs with Services

背景

我正在制作Service,它有一个列表可以在两个控制器之间共享。 首先,我按照本教程关注服务:

我成功地创建并执行了Plunker的基础教程:

问题

这里的问题是,当我单击表单按钮时,我需要向服务器发出HTTP GET请求,并在收到响应时更新服务列表。

为此,我首先尝试使用以下Plunker修改:

可以在服务中看到代码的笑话:

  // Create the factory that share the Fact
  app.factory('ListService', function($http) {
    var list = {};
    list.data = [];

    list.request = function(theHairColor) {
      var theUrl = "https://gnome-shop-fl4m3ph03n1x.c9users.io/api/v1/gnomes?hairColor=" + theHairColor;
      console.log(theUrl);
      $http({
        method: 'GET',
        url: theUrl,
        headers: {
          'Content-Type': 'application/json; charset=utf-8'
        }
      }).then(function successCallback(response) {
        list.data = response.data.entries; //does not work
        console.log(response.data.entries);
      }, function errorCallback(response) {
        console.log('Error: ' + response);
      });
    };

    return list;
  });

如果你尝试过,你会发现它根本不起作用,我真的不明白为什么。 在我之前提出的一个问题中,有人向我解释说它与引用有关,我应该替换list.data = response.data.entries; //does not work list.data = response.data.entries; //does not work用于以下内容:

//this works but is rather flimsy ....
list.data.length = 0;
Object.assign(list.data, response.data.entries);

这在行动中起作用,但我发现它相当直观:

还给出了另一个建议,我应该将我的gnomeList控制器更改为:

app.controller("gnomeList", function(ListService) {
    var self = this;
    self.listService = ListService;
  });

然后直接遍历服务列表:

<div ng-controller="gnomeList as listCtrl">
      <p ng-repeat="gnome in listCtrl.listService.data">{{ gnome.id }}: {{ gnome.name }}</p>
</div>

哪个也有效,但将控制器直接附加到服务:

问题:

  1. 有没有其他方法可以使我的第一个代码示例(不起作用)工作?
  2. 哪种解决方案更可取?为什么? (哪一个更像Angulary ?)

问题是你最初复制gnomeList中的数据并按值传递。

app.controller("gnomeList", function(ListService) {
  var self = this;
  self.list = ListService.data;
});

当您的控制器在此处初始化时,它会将ListService.data的副本放入self.list 但是,更新服务中的值时,此控制器不会再次初始化,因此不会更新该值。

javascript中的对象通过引用传递。 就像你说的那样,你可以直接将服务放在范围内以使用它的数据,或者只需在对象上设置属性,然后再在范围上设置它们。 普兰克

使用Javascript

app.controller("gnomeList", function(ListService) {
  var self = this;
  self.list = ListService.value; // value is an object
});

// Create the factory that share the Fact
app.factory('ListService', function($http) {
  var list = {};
  list.value = {};

  list.request = function(theHairColor) {
    var theUrl = "https://gnome-shop-fl4m3ph03n1x.c9users.io/api/v1/gnomes?hairColor=" + theHairColor;
    console.log(theUrl);
    $http({
      method: 'GET',
      url: theUrl,
      headers: {
        'Content-Type': 'application/json; charset=utf-8'
      }
    }).then(function successCallback(response) {
      list.value.data = response.data.entries; // extend value object
    }, function errorCallback(response) {
      console.log('Error: ' + response);
    });
  };

  return list;
});

HTML

<div ng-controller="gnomeList as listCtrl">
  <p ng-repeat="gnome in listCtrl.list.data">{{ gnome.id }}: {{ gnome.name }}</p>
</div>

此外,最好使用内置的angular.extend来扩展对象。

所以这不起作用?

list.request = function(theHairColor) {
  var theUrl = "https://gnome-shop-fl4m3ph03n1x.c9users.io/api/v1/gnomes?hairColor=" + theHairColor;
  console.log(theUrl);
  $http({
    method: 'GET',
    url: theUrl,
    headers: {
      'Content-Type': 'application/json; charset=utf-8'
    }
  }).then(function success(data) {
    list.data = data;
    console.log(data);
    return data;
  });
};

这将是我们过去使用过的结构(我们现在使用Restangular),但是这个链接是一个很好的页面,可以看到有助于您的$ http。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM