【问题标题】:How do I update one controller with data from another controller with a service in angular?如何使用来自具有角度服务的另一个控制器的数据更新一个控制器?
【发布时间】:2013-01-17 22:04:33
【问题描述】:

我有 2 个控制器。第一个获取所选项目,第二个获取可用项目。

如何显示新选择的项目?

每个可用项目下方的按钮都有一个 ng-click,它调用一个名为 updateItem 的服务,我希望在其中进行更新。

我已经为此工作了一段时间,非常感谢任何帮助。 -谢谢

jsfiddle

<div ng-controller="seletedItemCtrl">
      <p><i>I want to update this item</i></p>
      <div ng-repeat="item in selectedItems">

      <ul>
          <li>{{item.color}}</li>
          <li>{{item.Distance}}</li>
          <li>{{item.height}}</li>
          <li>{{item.name}}</li>
          <li>{{item.year}}</li>
      </ul>
   </div>
</div >   
  ///////////////////////////////////////////////////
  <div ng-controller="availableItemsCtrl">
       <div ng-repeat="item in availableItems">
          <ul>
              <li>{{item.color}}</li> 
              <li>{{item.Distance}}</li>
              <li>{{item.height}}</li>
              <li>{{item.name}}</li>
              <li>{{item.year}}</li>
         </ul>
         <button ng-click = 'updateItem()' >select item</button>
      </div> 
   </div>

JS

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

function availableItemsCtrl($rootScope, $scope){
        $scope.availableItems =  {
    "Items": {
        "Item": {
            "Group1": [
                {
                    "color": "White",
                    "Distance": "NA",
                    "height": "3ft",
                    "name": "Underlift",
                    "year": "1955"

                  },
                  {
                    "color": "blue",
                    "Distance": "4M",
                    "height": "2ft",
                    "name": "Underlift",
                    "year": "1956"

                  },
                  {
                     "color": "red",
                     "Distance": "NA",
                     "height": "3ft",
                     "name": "Golen Leaf",
                     "year": "1968"

                   },
                   {
                      "color": "yellow",
                      "Distance": "22M",
                      "height": "10in",
                      "name": "Together",
                      "year": "1988"

                   }


              ]
          },

       }
   }
       $scope.availableItems = $scope.availableItems.Items.Item.Group1;
 }

 function seletedItemCtrl($rootScope, $scope){
         $scope.seletedItem =  {
              "Items":{
                  "Item":{
                     "Group1":[{

                         "color": "black",
                         "Distance": "2M",
                         "height": "1in",
                         "name": "never",
                         "year": "1922"

                          }
                       ]
                     }
                   }
                 }
    $scope.selectedItems = $scope.seletedItem.Items.Item.Group1;

  }
    app.service("updateItem", function(){

      console.log('update item');

   });

【问题讨论】:

  • @pkozlowski.opensource,他确实提供了一个小提琴(我想你只是在文本中错过了它)。
  • 糟糕,对不起,你是对的!

标签: json angularjs


【解决方案1】:

请记住,您的 $scope 不是您的模型;你的$scope 是你附加你的模型的东西。 Angular 鼓励您构建自己的模型对象来描述应用程序的行为。在此示例中,您似乎具有“可用项目”和“选定项目”的域概念。这是一个简单的服务,可为您提供这些概念的模型:

app.factory('Items', function () {
    var Items = {
        availableItems: [],
        selectedItems: []
    };
    Items.addAvailableItem = function (item) {
        Items.availableItems.push(item);
    };
    Items.selectItem = function (item) {
        Items.selectedItems.push(item);
    };
    return Items;
});

所以现在你有了这个Items 服务,它有一个addAvailableItem 方法,它接受一个项目并将其添加到availableItems 数组中,还有一个selectItem 方法,它接受一个项目并将它添加到selectedItems 数组。您现在可以使用控制器的范围将这两个数组绑定到您的视图:

app.controller('someController', function ($scope, Items) {
    $scope.availableItems = Items.availableItems;
};

这是一个 jsFiddle,它使用您提供的代码作为起点演示了该概念(它还演示了在模块中定义控制器的更好方法):http://jsfiddle.net/BinaryMuse/kV4mK/

【讨论】:

    【解决方案2】:

    这是我的尝试:fiddle

    我不太了解您的数据结构,所以我对它们进行了一些更改。但是,我认为重要的部分在那里——如何在控制器之间共享数据。

    function availableItemsCtrl($rootScope, $scope, itemService) {
        $scope.availableItems = [{
            "color": "White",
             ...
        }];
        $scope.updateItem = itemService.storeSelectedItem;
        itemService.storeSelectedItem($scope.availableItems[0]);
    }
    
    function selectedItemCtrl($scope, itemService) {
        $scope.selectedItem = itemService.selectedItem;
    }
    
    app.service("itemService", function () {
        var that = this;
        this.selectedItem = {};
        this.storeSelectedItem = function (item) {
            angular.copy(item, that.selectedItem);
            console.log('update item', item);
        }
    });
    

    我花了很长时间才弄清楚我必须使用 angular.copy() 而不是

    that.selectedItem = item;
    

    因为上述内容会导致为 selectedItem 分配一个新的数组引用,而 selectedItemCtrl 不会注意到 - 即 $scope.selectedItem 仍将引用前一个数组。

    我很想看看其他人的想法。

    更新:看来我完全错过了您想要支持多个选定项目的事实。

    【讨论】:

    • 这很好地展示了这个概念——我不会因为特定领域模型的细节而自责,因为它不是很清楚。
    • 谢谢@Brandon。我喜欢你使用 factory() 而不是 service()——我从不喜欢 this that 的东西。我也喜欢你如何将所有模型移到服务中。 (我必须开始更多地这样做。)
    • 谢谢 :) 我通常使用 CoffeeScript,它几乎不需要 this/that。将所有数据从$scope 转移到服务中可能很难养成这样做的习惯,但是当需要更改域模型时,它会带来成倍的回报!
    猜你喜欢
    • 2014-01-03
    • 2017-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    • 2017-10-30
    相关资源
    最近更新 更多