0

我创建了一个小型单页 Angular 应用程序。我有每个项目都可见的主视图。我需要允许用户“收藏”一个项目并让该项目显示在其他两个视图上。用户还可以从三个视图中的任何一个中“取消收藏”该项目,基本上将其从其他两个视图中删除(仅在主视图中显示。)

我可以使用复选框更改模型,但我不知道,因为它没有在外部 JSON 中更新。我想找到一种方法将视图更改保存到模型,然后保存模型,以便它在所有视图中持久存在。

这是标记:

<label><input type="checkbox" ng-model="item.isFavorited"></input></label>

控制器以 JSON 格式请求模型:

[   
   {
        "isFavorited": true,
        "name": "Ford Taurus",
        "vendor": "Hertz"
    }
]

我看过 $watch、ng-change、服务、指令等。我认为我误解了 Angular 的一个基本部分。关于如何做到这一点的任何想法?

4

1 回答 1

0

您的问题是由孤立的范围引起的。当您在主控制器内部或在主控制器旁边创建新控制器时,它们每个都有自己的范围。子作用域可以看到他的父作用域,但它处于只读模式。

您的问题有两种解决方案。您可以使用 rootScope 来存储项目并在 rootScope 中添加函数来编辑此数组。这是一个糟糕的设计。

做你想做的事情的真正 Angular 方法是使用服务。服务由所有控制器共享,甚至在视图之间持续存在。该服务将保存数据并让您通过方法访问它。

这项服务可以完成这项工作:

var app = angular.module('plunker', []);

app.factory('FavoritesService', function() {
  var items = [{
        "isFavorited": false,
        "name": "Ford Taurus",
        "vendor": "Hertz",
        "id" : 1
    }, 
    {
        "isFavorited": false,
        "name": "Honda Civic",
        "vendor": "Hertz",
        "id" : 2
    },
    {
        "isFavorited": false,
        "name": "Ford F150",
        "vendor": "Other",
        "id" : 3
    }];

    return {
      getItems: function() {
        return items;
      },
      addItem: function(item) {
        var currentIndex = items.length + 1;
        item.id=currentIndex;
        items.push(item);
      },
      toggleFavorite: function(id) {
        for (var i = 0; i < items.length; i++) {
          if (id == items[i].id) {
            items[i].isFavorited = !items[i].isFavorited;
            break;
          }
        }
      },
      getFavorites: function() {
        var fav = [];
        for (var i = 0; i < items.length; i++) {
          if (items[i].isFavorited) {
            fav.push(items[i]);
          }
        }
        return fav;
      }
    }
  });

该服务允许您获取数据、切换收藏标记或添加新项目。

然后,您将使用控制器在视图和数据之间创建链接:

$scope.getItems = function() {
  return FavoritesService.getItems();
}

$scope.toggleFavorite = function(id) {
  return FavoritesService.toggleFavorite(id);
}

最后,您可以使用以下内容迭代数据:

<div ng-repeat="item in getItems()">{{item.name}} - {{item.isFavorited}}
  <button ng-click="toggleFavorite(item.id)">Toggle favorite</button>
</div>

我做了一个 plunker,向你展示如何使用它。您会注意到,我在项目中添加了一个 ID 以帮助我识别它们,但您可以不使用它。在 plunker 中,您可以看到 3 个共享相同数据的控制器。子控制器仅显示收藏夹并允许您添加新项目。它向您展示了您从服务中获得了多少控制权。

普朗克

祝你好运!

于 2013-08-13T23:31:41.070 回答