Как обновить один контроллер данными от другого контроллера с помощью службы в 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 все равно ссылался бы на предыдущий массив.
Мне будет интересно узнать, что другие придумали.
Обновление: похоже, что я полностью упустил тот факт, что вы хотите поддерживать несколько выбранных элементов.