Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/428.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在控制器和服务之间共享数据 背景_Javascript_Angularjs_Service_Controllers - Fatal编程技术网

Javascript 在控制器和服务之间共享数据 背景

Javascript 在控制器和服务之间共享数据 背景,javascript,angularjs,service,controllers,Javascript,Angularjs,Service,Controllers,我正在制作一个服务,它有一个列表可以在两个控制器之间共享。首先,我遵循了关于服务的本教程: 我成功地创建并执行了关于Plunker的基本教程: 问题 这里的问题是,当我单击表单按钮时,我需要向我的服务器发出HTTPGET请求,并在收到响应时更新服务列表 为了实现这一点,我首先尝试使用以下Plunker修改: 代码的笑话可以在服务中看到: // Create the factory that share the Fact app.factory('ListService'

我正在制作一个服务,它有一个列表可以在两个控制器之间共享。首先,我遵循了关于服务的本教程:

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

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

为了实现这一点,我首先尝试使用以下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//以下情况不起作用

//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>

{{{gnome.id}:{{{gnome.name}

它也可以工作,但将控制器直接连接到服务:

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

    这可能是我们过去使用过的结构(我们现在使用Restanglar),但是这个链接是一个关于$http的链接,它可以帮助您。

    问题是您最初复制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

    
    

    {{{gnome.id}:{{{gnome.name}


    此外,最好使用内置扩展对象。

    可能重复的@estus阅读这两个问题,你会明白,虽然相关,但它们不是重复的。它看起来像同一个问题,但经过更新和碰撞。有两种选择,而且已经提出了。您应该返回服务承诺。或者您应该返回一个自填充对象,带有
    object.assign
    。它并不脆弱。这就是内置的
    $resource
    的工作原理(在本例中,您可以使用它,而不是重新发明轮子)。这个问题集中在一件事上:这两个选项中哪一个角度更大??另一个只是解决了一个存在的问题。这篇文章的重点是“哪种修复更可取”。它们是两个不同的问题。它们的角度是相等的。这是一个合适的解决办法。如前所述,$resource使用这种方法。但是在这种情况下,还应该从
    请求中返回承诺。你永远不知道什么时候需要它(至少对于测试而言)。