Angular 绑定到数组中的存在,或者,高性能计算属性
Angular binding to existence in array, or, performant computed properties
问题
我想知道是否有一种简洁、高效的方法可以将 angular 视图绑定到数组中特定项目的 existence。基本上,我在一页上有两个控制器。控制器 A 可以删除或添加由服务注入的数组中的项目。我希望注入了相同服务的控制器 B 在我从控制器 A 中删除或添加时更新其视图。
龙虾的问题
假设我正在创建一个龙虾约会网站。我有两个并排的视图:
最热的龙虾视图显示了海洋中最热的龙虾列表。如果这些龙虾中的任何一个碰巧是你的朋友,它的列表项将被突出显示并有一条消息说你是朋友。
龙虾朋友观点与最火龙虾观点同页。如果我从龙虾朋友视图中解除对龙虾的友好(即从 lobsterFriend
数组中删除龙虾),最热门的龙虾视图应相应更新,并停止突出显示不友好的龙虾。
我想要一个适用于大量龙虾的解决方案。
设置
免责声明:此问题中的代码仅用于说明目的。我实际上并不是在为龙虾创建约会网站。
我有一个要注入两个控制器的 angular 服务。服务 returns 一个对象数组。
lobsterFriendService
,管理龙虾好友的服务:
angular.module('lobsterDating')
.factory('lobsterFriendService', function($http) {
return {
// An array of lobsters
lobsterFriends: $http.get('lobsterApi/lobsterFriends/'),
addLobsterFriend: function (lobster) {
this.lobsterFriends.push(lobster);
$http.post('lobsterApi/lobsterFriends/', lobster);
},
deleteLobsterFriend: function (crustaceanId) {
this.lobsterFriends = this.lobsterFriends.filter(function (lobster) { return lobster.id !== crustaceanId; });
$http.delete('lobsterApi/lobsterFriends/', crustaceanId);
}
}
});
LobsterFriendsCtrl
,一个好友列表的控制器,注入了lobsterFriendService
:
angular.module('lobsterDating')
.controller('LobsterFriendsCtrl', ["lobsterFriendService", function(lobsterFriendService) {
$scope.removeFriend = function (lobsterId) {
lobsterFriendService.deleteLobsterFriend(lobsterId);
}
}]);
HottestLobsterCtrl
,最火龙虾专页控制器:
angular.module('lobsterDating')
.controller('HottestLobstersCtrl', ["lobsterFriendService", "hottestLobsters" function(lobsterFriendService, hottestLobsters) {
$scope.model = {
hottestLobsters: hottestLobsters
};
$scope.lobsterIsFriend = function (lobsterId) {
return lobsterFriendService.lobsterFriends.contains(lobsterId);
}
$scope.addLobsterFriend = function (lobster) {
lobsterFriendService.addLobsterFriend(lobster);
}
}]);
hottestLobsters.html
,视图绑定到HottestLobsterCtrl
:
<div ng-repeat="lobster in model.hottestLobsters">
<div class="lobsterFriend" ng-if="lobsterIsFriend(lobster.id)">{{lobster.name}} is your friend ;)</div>
<div class="twoClawsUp" ng-if="lobsterIsFriend(lobster.id)" ng-click="addLobsterFriend(lobster)">Two claws up for {{lobster.name}}!</div>
</div>
可能的解决方案
- 在
lobsterFriends
数组上设置监视。当它更新时,我们可以在 HottestLobsterCtrl
控制器上更新一些 属性,触发摘要等。我认为这会相当昂贵。
- 每当龙虾成为好友或解除好友时发出事件。如果可能的话,这是一条我想避免走下坡路的路径,因为我已经在那里注入了一个带有实际对象的服务。
- 使用某种可以很好地处理计算属性的帮助程序库。
- ????请帮忙?
您要做的是将数据保存在单个 obj/array 中,当您更新时,只需更改该对象和数组的值,而不是保留两个数组。您可以将其视为主阵列。这样做的原因是因为 obj/array 是通过引用传递的,因此它们在哪个控制器中并不重要,它将是相同的数据。 Plunker Example
service('dataHolder', function(){
this.data = [{
name : 'Joe',
isFriend: false
},
{
name : 'Michelle',
isFriend: false
},
{
name : 'Adam',
isFriend: true
},
{
name : 'West',
isFriend: false
}]
})
在您的示例中,如果您找到一种通过合并将 hottestLobsters 和 LobsterFriends 合并到单个对象中并通过属性控制它们的方法,则无需任何 watch 或 broadcast 。就像共享同一个范围一样简单。
问题
我想知道是否有一种简洁、高效的方法可以将 angular 视图绑定到数组中特定项目的 existence。基本上,我在一页上有两个控制器。控制器 A 可以删除或添加由服务注入的数组中的项目。我希望注入了相同服务的控制器 B 在我从控制器 A 中删除或添加时更新其视图。
龙虾的问题
假设我正在创建一个龙虾约会网站。我有两个并排的视图:
最热的龙虾视图显示了海洋中最热的龙虾列表。如果这些龙虾中的任何一个碰巧是你的朋友,它的列表项将被突出显示并有一条消息说你是朋友。
龙虾朋友观点与最火龙虾观点同页。如果我从龙虾朋友视图中解除对龙虾的友好(即从
lobsterFriend
数组中删除龙虾),最热门的龙虾视图应相应更新,并停止突出显示不友好的龙虾。
我想要一个适用于大量龙虾的解决方案。
设置
免责声明:此问题中的代码仅用于说明目的。我实际上并不是在为龙虾创建约会网站。
我有一个要注入两个控制器的 angular 服务。服务 returns 一个对象数组。
lobsterFriendService
,管理龙虾好友的服务:
angular.module('lobsterDating')
.factory('lobsterFriendService', function($http) {
return {
// An array of lobsters
lobsterFriends: $http.get('lobsterApi/lobsterFriends/'),
addLobsterFriend: function (lobster) {
this.lobsterFriends.push(lobster);
$http.post('lobsterApi/lobsterFriends/', lobster);
},
deleteLobsterFriend: function (crustaceanId) {
this.lobsterFriends = this.lobsterFriends.filter(function (lobster) { return lobster.id !== crustaceanId; });
$http.delete('lobsterApi/lobsterFriends/', crustaceanId);
}
}
});
LobsterFriendsCtrl
,一个好友列表的控制器,注入了lobsterFriendService
:
angular.module('lobsterDating')
.controller('LobsterFriendsCtrl', ["lobsterFriendService", function(lobsterFriendService) {
$scope.removeFriend = function (lobsterId) {
lobsterFriendService.deleteLobsterFriend(lobsterId);
}
}]);
HottestLobsterCtrl
,最火龙虾专页控制器:
angular.module('lobsterDating')
.controller('HottestLobstersCtrl', ["lobsterFriendService", "hottestLobsters" function(lobsterFriendService, hottestLobsters) {
$scope.model = {
hottestLobsters: hottestLobsters
};
$scope.lobsterIsFriend = function (lobsterId) {
return lobsterFriendService.lobsterFriends.contains(lobsterId);
}
$scope.addLobsterFriend = function (lobster) {
lobsterFriendService.addLobsterFriend(lobster);
}
}]);
hottestLobsters.html
,视图绑定到HottestLobsterCtrl
:
<div ng-repeat="lobster in model.hottestLobsters">
<div class="lobsterFriend" ng-if="lobsterIsFriend(lobster.id)">{{lobster.name}} is your friend ;)</div>
<div class="twoClawsUp" ng-if="lobsterIsFriend(lobster.id)" ng-click="addLobsterFriend(lobster)">Two claws up for {{lobster.name}}!</div>
</div>
可能的解决方案
- 在
lobsterFriends
数组上设置监视。当它更新时,我们可以在HottestLobsterCtrl
控制器上更新一些 属性,触发摘要等。我认为这会相当昂贵。 - 每当龙虾成为好友或解除好友时发出事件。如果可能的话,这是一条我想避免走下坡路的路径,因为我已经在那里注入了一个带有实际对象的服务。
- 使用某种可以很好地处理计算属性的帮助程序库。
- ????请帮忙?
您要做的是将数据保存在单个 obj/array 中,当您更新时,只需更改该对象和数组的值,而不是保留两个数组。您可以将其视为主阵列。这样做的原因是因为 obj/array 是通过引用传递的,因此它们在哪个控制器中并不重要,它将是相同的数据。 Plunker Example
service('dataHolder', function(){
this.data = [{
name : 'Joe',
isFriend: false
},
{
name : 'Michelle',
isFriend: false
},
{
name : 'Adam',
isFriend: true
},
{
name : 'West',
isFriend: false
}]
})
在您的示例中,如果您找到一种通过合并将 hottestLobsters 和 LobsterFriends 合并到单个对象中并通过属性控制它们的方法,则无需任何 watch 或 broadcast 。就像共享同一个范围一样简单。