与数组中存在的角度绑定,或高性能计算属性

Angular binding to existence in array, or, performant computed properties

本文关键字:高性能 计算 属性 绑定 数组 存在      更新时间:2023-09-26

问题

我想知道是否有一种简洁、高性能的方法可以将角度视图绑定到数组中特定项目的存在。基本上,我在一页上有两个控制器。控制器 A 可以删除或添加服务注入的数组中的项。我希望注入相同服务的控制器 B 在我从控制器 A 中删除或添加时更新其视图。

龙虾的问题

假设我正在创建一个龙虾约会网站。我有两个并排的观点:

  • 最热的龙虾视图显示了海洋中最热的龙虾列表。如果这些龙虾中的任何一只碰巧是您的朋友,其列表项将突出显示并显示一条消息,说明您是朋友。

  • 虾好友视图与最热门的龙虾视图位于同一页面上。如果我从龙虾好友视图中取消与龙虾好友关系(即从lobsterFriend数组中删除龙虾),最热的龙虾视图应相应地更新,并停止突出显示未交友的龙虾。

我想要一个适用于大量龙虾的解决方案。

设置的设置

免责声明:此问题中的代码仅用于说明目的。我实际上并不是在为龙虾创建一个约会网站。

有一个角度服务,我正在注入到两个控制器中。该服务返回对象数组。

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>

可能的解决方案

  1. lobsterFriends阵列上设置监视。当它更新时,我们可以更新HottestLobsterCtrl控制器上的一些属性,触发摘要等。我认为这将是相当昂贵的。
  2. 每当龙虾成为好友或非好友时,都会发出一个事件。如果可能的话,这是我想避免的路径,因为我已经在向服务注入实际对象。
  3. 使用某种可以很好地处理计算属性的帮助程序库。
  4. ????请帮忙?
您要

做的是将数据保存在单个obj/数组中,并且在更新时,只需更改该对象和数组的值,而不是保留两个数组。 您可以将其视为主数组。 这样做的原因是 obj/array 是通过引用传递的,因此它们在哪个控制器中并不重要,它将是相同的数据。 普伦克示例

service('dataHolder', function(){
  this.data = [{
    name : 'Joe',
    isFriend: false
  },
  {
    name : 'Michelle',
    isFriend: false
  },
  {
    name : 'Adam',
    isFriend: true
  },
  {
    name : 'West',
    isFriend: false
  }] 
})

在您的示例中,如果您找到一种方法通过合并将最热门的龙虾和龙虾朋友组合到一个对象中并通过属性控制它们,则无需任何监视或广播。 这就像共享相同的范围一样。