我有一家工厂:
function PeriodDataService (APIService) {
var periodData = {}
periodData.refresh = function(user) {
APIService.query({ route:'period', id: user._id }, function(data) {
periodData.orders = data[0].orders
})
}
periodData.orders = []
periodData.preiod = 1
return periodData
}
angular
.module('app')
.factory('PeriodDataService', PeriodDataService)
还有一些控制器......比如这个,它使用工厂数据
function ProductionCtrl ($scope, PeriodDataService) {
$scope.board = PeriodDataService.board
$scope.period = PeriodDataService.period
}
angular
.module('loop')
.controller('ProductionCtrl', ProductionCtrl)
当我调用刷新时,Controlles不会更新数据。是什么原因?
PeriodDataService.refresh(user)
谢谢!
答案 0 :(得分:1)
问题是,当您拨打refresh
并且您的服务确实
periodData.orders = data[0].orders
您的服务正在将periodData.orders
属性更改为指向与初始化时指定的数组不同的数组(通过periodData.orders = []
)。
这会破坏您的控制器与服务中的数据阵列之间的连接,因为您的控制器设置为在您执行时指向原始阵列
$scope.orders = PeriodDataService.orders
(我实际上并未在您的示例代码中看到,但我认为您正在某处做某事)。
这简单地设置$scope.orders
等于与periodData.orders
相同的指针,从而指向内存中的原始数组,并允许控制器查看对该数组的更改。
当您的服务将periodData.orders
更改为其他指针时,没有任何内容会更改$scope.orders
的指针值,因此它仍然指向未更改的原始数组。
您可以通过不同的方式解决此问题。
您可以将服务.push()
新数据放入periodData.orders
,而不是将periodData.orders
设置为等于返回的数据数组。所以你的refresh
方法看起来像这样:
periodData.refresh = function(user) {
APIService.query({ route:'period', id: user._id }, function(data) {
periodData.orders.length = 0; // empty current orders array
// push the returned orders data into orders array
data[0].orders.forEach(function (item, index) {
periodData.orders.push(item);
});
});
};
只要你只是添加或删除原始数组,并且不重新定义它(不要做另一个periodData.orders =
),它应该可以正常工作。
或者,您可以创建一个新对象来保存orders
数组(以及您要公开的任何其他数据元素)并使用$scope
属性指向该对象而不是数组本身
所以你的服务看起来像这样:
function PeriodDataService (APIService) {
var periodDataSvc = {};
// create data object to hold service data
periodDataSvc.periodData = {
orders: [],
period: 1
};
periodDataSvc.refresh = function(user) {
APIService.query({ route:'period', id: user._id }, function(data) {
periodDataSvc.periodData.orders = data[0].orders
})
}
return periodDataSvc;
}
orders
数组现在在periodDataSvc.periodData.orders
更深一层。
你会有一个$scope
属性指向periodData
对象而不是orders
数组:
function ProductionCtrl($scope, PeriodDataService) {
$scope.periodData = PeriodDataService.periodData;
}
因此,在您的服务中,当您将orders
数组设置为等于APIService中返回的数组时,控制器将看到该更改,因为它正在观察periodData
对象,并且该对象的属性已更改。
当然,由于您更改了$scope
属性,因此任何引用orders
数组的标记都需要更改为引用periodData.orders
。例如:
<div ng-repeat="order in periodData.orders">{{order.id}}: {{order.item}}</div>
这里有一个显示两种方法的fiddle。
答案 1 :(得分:0)
我在工厂使用 $ rootScope ,在控制器中使用 $ scope。$ on 来解决此问题。 当我更改工厂时,我使用 $ rootScope。$ broadcast 告诉控制器我更改了它。
.factory('dataFactory', ['$http', '$rootScope', function ($http, $rootScope) {
var dataFactory = {
stock: null,
getStock: getStock
}
function getStock() {
$http.get("/api/itemfarmacia/").then(function success(res) {
dataFactory.stock = res.data;
$rootScope.$broadcast('dataFactory.stock');
}, function error(err) {
onsole.log("Bad request");
})
}
return dataFactory;
}])
并在控制器中
.controller('atencion', ["$scope", "$state", "dataFactory", function ($scope, $state, dataFactory) {
$scope.stock = dataFactory.stock;
dataFactory.getStock(); //wherever you execute this, $scope.stock will change
$scope.$on('dataFactory.stock', function () {
$scope.stock = dataFactory.stock; //Updating $scope
})
}])