Javascript 使用服务AngularJs 1.6.1在控制器之间共享数据 背景

Javascript 使用服务AngularJs 1.6.1在控制器之间共享数据 背景,javascript,angularjs,service,controllers,Javascript,Angularjs,Service,Controllers,我正在制作一个关于侏儒的普查应用程序。此应用程序显示所有侏儒的列表,并允许您对其进行筛选 问题 问题是过滤器不工作!我的gnome过滤器控制器无法与gnome列表控制器通信。为了解决这个问题,我尝试通过在StackOverflow中阅读以下答案来创建服务: 然而,在创建了我认为是答案的完美复制品之后,它仍然不起作用 代码 当应用程序第一次加载时,gnome list向gnome普查服务器发出请求,以获取所有gnome并显示它们 但是,gnome有很多,所以我提供了一个选项,通过使用gnom

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

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

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

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

但是,gnome有很多,所以我提供了一个选项,通过使用
gnome过滤器
,对它们进行过滤,并且只获取具有读取头发的gnome

不幸的是,即使我向服务器发出请求并得到答复,我的服务仍无法正常工作

/*全局角度*/
(功能(){
var app=angular.module(“普查”[]);
应用控制器(“gnomeFilter”,函数(数据共享){
var self=这个;
self.listServ=DataShareServ;
self.makeRequest=函数(){
self.listServ.request({
发型颜色:“红色”
});
};
});
应用控制器(“gnomeList”,功能(数据共享){
var self=这个;
self.listServ=DataShareServ;
self.listServ.request();
self.list=self.listServ.data;
});
//创建共享事实的工厂
app.factory('DataShareServ',函数($http){
var self=这个;
self.list={};
self.list.data=[];
self.list.request=函数(参数){
var theUrl=https://gnome-shop-fl4m3ph03n1x.c9users.io/api/v1/gnomes';
if(参数头发颜色)
theUrl=theUrl+“?hairColor=“+params.hairColor;
$http({
方法:“GET”,
url:theUrl,
标题:{
“内容类型”:“应用程序/json;字符集=utf-8”
}
}).then(函数成功回调(响应){
self.list.data=response.data.entries;
控制台日志(“已提交”);
},函数errorCallback(响应){
console.log('错误:'+响应);
});
};
返回self.list;
});
})();

得到红色!!
  • {{gnome.name}

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

self.list=response.data.entries
完成后,
self.list
DataShareServ.data
引用不同的对象

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

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

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

明显的问题是正在重新分配
self.list

self.list=response.data.entries
完成后,
self.list
DataShareServ.data
引用不同的对象

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

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

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

因为您正在将
DataShareServ
分配给
gnomeList
控制器的范围,所以您可以简单地迭代存储在服务中的数据,这些数据会在每次请求时更新和重新分配。这样,您就不必处理在不同控制器上同步对象的问题

这样,html将如下所示:

<li ng-repeat="gnome in listCtrl.listServ.data">
   {{gnome.name}}
</li>
这将始终为空,因为http请求是异步的。你需要处理承诺(或类似的事情)。请看angular的
$q
服务:


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

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

这样,html将如下所示:

<li ng-repeat="gnome in listCtrl.listServ.data">
   {{gnome.name}}
</li>
这将始终为空,因为http请求是异步的。你需要处理承诺(或类似的事情)。请看angular的
$q
服务:


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

我想通过使用rootScope,您可以轻松地在两个控制器之间共享数据。我致力于服务,根据社区的说法,哪一个似乎是更好的选择。@Majid这是一个糟糕的建议,不符合普遍接受的最佳实践我想你可以通过使用rootScope轻松地在两个控制器之间共享数据。我致力于服务,根据社区的说法,哪一个似乎是更好的选择。@Majid这是一个糟糕的建议,不符合普遍接受的最佳实践你好,你知道我能读到的关于角度建筑的任何读物吗?你提出了一个很好的观点,我想了解。不是关于Angular,不是。这些是常见的MVC(在Angular的上下文中,它更像是MVVM)概念。我在这里指的是通常被称为“胖模型,瘦控制器”(一个“关注点分离”原则的特例)。这是一个它可能看起来像什么的例子,路由器有点过于复杂,但给出了一些观点。无论如何,如果控制器中有$http,这意味着出现了问题