0

问题

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

龙虾的问题

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

  • 最热龙虾视图显示海洋中最热龙虾的列表。如果这些龙虾中的任何一个恰好是您的朋友,它的列表项将突出显示,并有一条消息说您是朋友。

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

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

设置

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

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

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. ???请帮忙?
4

1 回答 1

1

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

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 。这就像共享相同的范围。

于 2015-01-13T12:31:52.787 回答