以下是控制器的相关部分:
summaryAlertsApp.controller('FinalizedSummaryAlertsCtrl', ['$scope', 'summaryAlertsSvc', function ($scope, summaryAlertsSvc) {
$scope.alerts = summaryAlertsSvc.getFinalizedSummaryAlerts();
$scope.settleAlert = function (alert) {
summaryAlertsSvc.settleAlert(alert);
$scope.alerts = summaryAlertsSvc.getFinalizedSummaryAlerts();
}
}]);
我从视图中调用settleAlert,$ scope.alerts肯定被分配了一个新数组,但视图没有显示更改。
我已经被这一段时间困扰了一段时间,我似乎无法弄清楚为什么视图(基本上只是警报的重复次数)没有改变。我知道警报数组正在缩短,但更改并未反映在转发器中。
以下是观点:
<div ng-app="summaryAlertsApp" ng-controller="FinalizedSummaryAlertsCtrl">
<div ng-repeat="alert in alerts">
stuff
</div>
</div>
以下是整个服务:
summaryAlertsApp.factory('summaryAlertsSvc', ['$http', '$q', function ($http, $q) {
var factory = {};
var alerts;
var deferred = $q.defer();
$http({
url: "SummaryAlerts.aspx/GetAlerts",
method: "POST",
data: {},
headers: { 'Content-Type': 'application/json; charset=utf-8' }
})
.success(
function (data) {
deferred.resolve(data.d);
}
)
alertsPromise = deferred.promise;
alertsPromise.then(function (result) {
alerts = result;
}
)
factory.getFinalizedSummaryAlerts = function () {
var finalizedSummaryAlerts = [];
alertsPromise.then(function () {
for (i = 0; i < alerts.length; i++) {
var alert = alerts[i];
if (alert.affectedSummaries.length > 0) {
finalizedSummaryAlerts.push(alert);
}
}
}
)
return finalizedSummaryAlerts;
}
factory.getNewSummaryAlerts = function () {
var newSummaryAlerts = [];
alertsPromise.then(function () {
for (i = 0; i < alerts.length; i++) {
var alert = alerts[i];
if (alert.affectedSummaries.length == 0) {
newSummaryAlerts.push(alert);
}
}
return newSummaryAlerts;
})
}
factory.settleAlert = function (alert) {
$http({
url: "SummaryAlerts.aspx/SettleAlert",
method: "POST",
data: {articlePMID: alert.PMID},
headers: { 'Content-Type': 'application/json; charset=utf-8' }
})
.success(
function (data) {
alerts.splice(alerts.indexOf(alert), 1);
}
)
}
return factory;
}]);
答案 0 :(得分:0)
由于finalizedSummaryAlerts
在promise中异步更新,因此只有在promise初始化后才会获得该变量的状态,这实际上是一个空数组。
解决这个问题的方法是让factory.getNewSummaryAlerts
返回一个promise并在该promise的then
子句中更新scope变量
即:
$scope.settleAlert = function (alert) {
summaryAlertsSvc.settleAlert(alert);
summaryAlertsSvc.getFinalizedSummaryAlerts().then(function(alerts){
$scope.alerts = alerts;
};
}
和
factory.getFinalizedSummaryAlerts = function () {
var finalizedSummaryAlerts = [];
return alertsPromise.then(function () {
for (i = 0; i < alerts.length; i++) {
var alert = alerts[i];
if (alert.affectedSummaries.length > 0) {
finalizedSummaryAlerts.push(alert);
}
}
return finalizedSummaryAlerts;
}
);
}
请阅读承诺,您的服务中发生了很多奇怪的事情,特别是处理需要清理的http响应
以下是我修复您服务的简短尝试:
summaryAlertsApp.factory('summaryAlertsSvc', ['$http', function ($http) {
var factory = {};
var alerts;
// NOT NEEDED
//var deferred = $q.defer();
// You assumed that a promise can be executed multiple times
// which is not the case, it can only be resolved once
// If you want to DRY up your code, create a function that returns a new promise
function getAlertsPromise(){
return $http({
url: "SummaryAlerts.aspx/GetAlerts",
method: "POST",
data: {},
headers: { 'Content-Type': 'application/json; charset=utf-8' }
})
.then(function(response){
// most http responses carry the data inside the response.data value
alerts = result.data;
// we will pass data only to the chained then functions
return result.data;
});
/// Promises resolve on their own, deferred.resolve is unneccessary
/// Also whenever you intercept a promise in a then/success clause
/// you need to return some value to pass it on to chained then/success functions
///
/// What you did here is intercept a value, do something with it and not return anything
/// which meant that chained 'then' functions received an undefined value
///
//.success(
// function (data) {
// deferred.resolve(data.d);
//}
}
// THis returns a promise which resolves with a value of finalizedSummaryAlerts
factory.getFinalizedSummaryAlerts = function () {
var finalizedSummaryAlerts = [];
return getAlertsPromise().then(function (data) {
for (i = 0; i < data.length; i++) {
var alert = data[i];
if (alert.affectedSummaries.length > 0) {
finalizedSummaryAlerts.push(alert);
}
}
return finalizedSummaryAlerts;
}
);
};
// THis returns a promise which resolves with a value of newSummaryAlerts
factory.getNewSummaryAlerts = function () {
var newSummaryAlerts = [];
return getAlertsPromise().then(function (data) {
for (i = 0; i < data.length; i++) {
var alert = data[i];
if (alert.affectedSummaries.length === 0) {
newSummaryAlerts.push(alert);
}
}
return newSummaryAlerts;
});
};
factory.settleAlert = function (alert) {
return $http({
url: "SummaryAlerts.aspx/SettleAlert",
method: "POST",
data: {articlePMID: alert.PMID},
headers: { 'Content-Type': 'application/json; charset=utf-8' }
})
.success(
function (data) {
alerts.splice(alerts.indexOf(alert), 1);
}
);
};
return factory;
}]);
请阅读Angular $ q以及传统使用示例的$ http文档
答案 1 :(得分:0)
问题出在方法summaryAlertsSvc.settleAlert中 由于它正在改变模型,因此getFinalizedSummaryAlerts正在进行计算。由于summaryAlertsSvc.settleAlert在成功时更改模型,因此getFinalizedSummaryAlerts
解决方案是让settleAlert返回一个承诺:
factory.settleAlert = function (alert) {
var deferred = $q.defer();
$http({
url: "FinalizedSummaryAlerts.aspx/SettleAlert",
method: "POST",
data: { articlePMID: alert.PMID },
headers: { 'Content-Type': 'application/json; charset=utf-8' }
})
.success(
function (data) {
alerts.splice(alerts.indexOf(alert), 1);
deferred.resolve();
}
)
return deferred.promise;
}
然后只有在完成执行后才调用getFinalizedSummaryAlerts:
summaryAlertsSvc.settleAlert(alert).then(function () {
$scope.alerts = summaryAlertsSvc.getFinalizedSummaryAlerts();
})