Angular 绑定到数组中的存在,或者,高性能计算属性

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

问题

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

龙虾的问题

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

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

设置

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

我有一个要注入两个控制器的 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>

可能的解决方案

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

您要做的是将数据保存在单个 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 。就像共享同一个范围一样简单。