Как обновить один контроллер данными от другого контроллера с помощью службы в angular?

У меня есть 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');

   });

Ответ 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 новую ссылку на массив, которую selectItemCtrl не заметил бы - то есть $scope.selectedItem все равно ссылался бы на предыдущий массив.

Мне будет интересно узнать, что другие придумали.

Обновление: похоже, что я полностью упустил тот факт, что вы хотите поддерживать несколько выбранных элементов.