我有一个工厂:
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)
当我调用刷新时,控件不会更新那里的数据。原因何在?
PeriodDataService.refresh(user)
谢谢!
问题是,当您调用refresh
并且您的服务确实
periodData.orders = data[0].orders
您的服务正在更改 periodData.orders
属性以指向与初始化它时设置为指向的数组不同的数组(通过 periodData.orders = []
)。
这会断开控制器和服务中的数据数组之间的连接,因为控制器设置为在执行此操作时指向原始数组
$scope.orders = PeriodDataService.orders
(我实际上没有在您的示例代码中看到,但我认为您正在某处执行)。
这简单地将$scope.orders
设置为等于与periodData.orders
相同的指针,从而指向内存中的原始数组,并允许控制器查看对该数组的更改。
当您的服务periodData.orders
更改为不同的指针时,$scope.orders
的指针值不会发生任何变化,因此它仍然指向原始数组,该数组没有更改。
有不同的方法可以解决此问题。
方法1
可以让服务将新数据.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 =
),它应该可以正常工作。
方法2
或者,您可以创建一个新对象来保存 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
更深一级。
您将有一个指向periodData
对象而不是orders
数组的 $scope
属性:
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>
这里有一个小提琴展示了这两种方法。
我在工厂中使用了$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
})
}])