使用Service AngularJs 1.6.1在控制器之间共享数据



背景

我正在制作一个关于侏儒的人口普查应用程序。这个应用程序显示所有gnome的列表,并允许您对其进行筛选。

问题

问题是过滤器不工作!我的gnome-filter控制器无法与gnome-list控制器通信。为了解决这个问题,我尝试通过阅读StackOverflow中的答案来创建一个服务:

  • https://stackoverflow.com/a/21920241/1337392

然而,在创建了我认为是答案的精细复制品之后,它仍然不起作用。

代码

当应用程序首次加载时,gnome-list向gnome普查服务器发出请求,以获取所有gnome并显示它们。

然而,有很多gnome,所以我为您提供了一个选项,通过使用gnome-filter来过滤它们,并且只获取具有read头发的gnome。

不幸的是,尽管我向服务器提出了请求,并得到了答复,但我的服务无法工作。。。

/*global angular*/
(function() {
var app = angular.module("census", []);
app.controller("gnomeFilter", function(DataShareServ) {
var self = this;
self.listServ = DataShareServ;
self.makeRequest = function() {
self.listServ.request({
hairColor: "red"
});
};
});
app.controller("gnomeList", function(DataShareServ) {
var self = this;
self.listServ = DataShareServ;
self.listServ.request();
self.list = self.listServ.data;
});
// Create the factory that share the Fact
app.factory('DataShareServ', function($http) {
var self = this;
self.list = {};
self.list.data = [];
self.list.request = function(params) {
var theUrl = 'https://gnome-shop-fl4m3ph03n1x.c9users.io/api/v1/gnomes';
if (params.hairColor)
theUrl = theUrl + "?hairColor=" + params.hairColor;
$http({
method: 'GET',
url: theUrl,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).then(function successCallback(response) {
self.list.data = response.data.entries;
console.log("submitted");
}, function errorCallback(response) {
console.log('Error: ' + response);
});
};
return self.list;
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<body>
<!-- Search functionality -->
<form ng-controller="gnomeFilter as filterCtrl" ng-submit="filterCtrl.makeRequest()">
<button type="submit">Get Reddies !!</button>
</form>
<!-- Gnomes list -->
<div ng-controller="gnomeList as listCtrl">
<ul>
<li ng-repeat="gnome in listCtrl.list">
{{gnome.name}}
</li>
</ul>
</div>
</body>

问题

  1. 我的代码出了什么问题?我该怎么修

由于您将DataShareServ分配给gnomeList控制器的作用域,因此您可以简单地迭代存储在服务中的数据,该数据在每次请求时都会更新和重新分配。这样你就不必在不同的控制器上同步你的对象了。

这样一来,html就会看起来像这样:

<li ng-repeat="gnome in listCtrl.listServ.data">
{{gnome.name}}
</li>

编辑

另外请注意,您的代码中还有另一个问题。在gnomeList控制器中,您正在调用服务的request方法,该方法对某个端点执行异步请求,并将其结果分配给本地变量,但您不必等待将控制器变量分配给服务变量的结果。简而言之:

self.list = self.listServ.data;

这将始终为空,因为http请求是异步的。你需要处理承诺(或类似的事情)。从以下角度来看$q服务:https://docs.angularjs.org/api/ng/service/$q

请注意,如果您使用我的解决方案,这并不重要,只是想指出这一点。

显而易见的问题是self.list正在被重新分配。

self.list = response.data.entries完成之后,self.listDataShareServ.data指代不同的对象。

它可以通过使用保持对同一对象的引用来解决

self.list.length = 0;
Object.assign(self.list, response.data.entries);

另一个问题是控制器做了它不应该做的工作,这导致了设计问题。$http请求不应在控制器中执行。DataShareServ服务应该包含修改其自身数据的方法。

最新更新