我正在尝试根据该页面可用的文章数量动态设置页面类型。所以,如果我有2篇或更多文章,请给我列出页面,如果我有,请给我详细信息页面。问题是,即使是我可以在页面上看到我的文章,length
属性总是返回0.需要一些帮助来解决这个问题。这是整个控制器的代码:
所以,现在这种方式有效:(请参阅图片,了解我在控制台中获得的内容)
//Public page - List of articles
bordonHillControllers.controller('PageListCtrl', ['$scope', '$location' , 'Page_Articles', '$routeParams', function ($scope, $location, Page_Articles, $routeParams) {
$scope.pageId = $routeParams.pageId;
var deferred = $.Deferred();
var articles = Page_Articles.get({ id: $scope.pageId });
deferred.resolve(articles);
deferred.promise().then(function successCallback(data, status, headers, config) {
$scope.articles = data;
if ([$scope.articles[0]].length == 1) {
console.log([$scope.articles])
//$location.path('/article/' + article.id);
}
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
return $scope.errorMessage = "Something went wrong!";
})
$scope.formatDate = function (date) {
var dateOut = new Date(date);
return dateOut;
};
}])
这是我设置服务的地方:
bordonHillServices.factory('Page_Articles', ['$resource',
function ($resource) {
return $resource('/api/ArticlesByPageApi/', {}, {
get: { method: 'GET', params: { id: 'pages' }, isArray: true },
});
}])
这是发送数据的服务:
//Get: Api/HomeApi
[HttpGet]
public async Task<HttpResponseMessage> Get(int id)
{
HttpResponseMessage response;
try
{
var articles = await Task.FromResult(context.Articles.Where(p => p.Page_ID == id).Select(p => new { DatePublished = p.DatePublished, ID = p.ID, Image_ID = p.Image_ID, IsHomeFeatured = p.IsHomeFeatured, IsHomeMain = p.IsHomeMain, IsNewsFeatured = p.IsNewsFeatured, IsNewsMain = p.IsNewsMain, Page_ID = p.Page_ID, Preview = p.Preview, Title = p.Title, Image = context.Images.FirstOrDefault(o => o.ID == p.Image_ID) }).ToList());
response = Request.CreateResponse(HttpStatusCode.OK, articles);
}
catch (System.Exception ex)
{
response = Request.CreateResponse(HttpStatusCode.BadRequest, "Could Not Load The Requested Data");
throw ex;
}
return response;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.context.Dispose();
}
base.Dispose(disposing);
}
再说一次,只是为了确保我很清楚:我需要返回$scope.articles
中的文章数量。
我也试过$scope.articles.data
(在使用deffered之前,我认为因为api运行async可能是问题,但仍然无效)。
这是html的模板:
$templateCache.put(
'~/Views/Home/pageList.cshtml',
'<section id="appContent" ng-controller="PageListCtrl">' +
'<div class="row">' +
'<div class="form-group form-horizontal" style="display: flex;">' +
'<label class="padding10">Search: </label>' +
'<input class="padding10 form-control" style="display:inline" ng-model="query">' +
'<label class="padding10">Order: </label>' +
'<select class="padding10 form-control" style="display:inline" ng-model="orderProp">' +
'<option value="title">Alphabetical</option>' +
'<option value="datePublished">By Date</option>' +
'</select>' +
'</div>' +
'</div>' +
'<div ng-repeat="article in articles | filter:query | orderBy:orderProp | filter: { isNewsFeatured : false}" class="col-md-12 article-listing">' +
'<br /><br />' +
'<div class="row">' +
'<div class="col-sm-12 col-md-4 col-lg-2" ng-if="article.image.path">' +
'<a href="#/article/{{article.id}}" class="thumb thumbnail">' +
'<img ng-src="{{article.image.path}}" alt="{{article.title}} image:">' +
'</a>' +
'</div>' +
'<a href="#/article/{{article.id}}"><h3>{{article.title}}</h3></a>' +
'<p class="publishedDate">Published on: <span ng-bind="formatDate(article.datePublished) | date"></span></p>' +
'<div class="col-sm-12 col-md-8 col-lg-10 preview">{{article.preview}}</div>' +
'<br />' +
'</div>' +
'<div class="buttons">' +
'<a href="#/article/{{article.id}}">Read more...</a>' +
'</div>' +
'<hr />' +
'</div>' +
'</section>'
)
答案 0 :(得分:0)
好的,有些事情出错了,我认为对承诺存在一些误解。
首先你创建一个延迟,然后你立即解决:
deferred = $.Deferred();
deferred.resolve(Page_Articles.get({ id: $scope.pageId }));
承诺应在get请求完成后由服务解决,而不是由您的控制器解决!
Page_Articles.get({ id: $scope.pageId })
本身可能会返回一个承诺(我不知道这个),但无论它返回什么,您可能会在get-Request完成之前解析deferred
。
所以延迟将使用我想的空对象解决(Page_Articles的代码会有用!)。这就是data.length
为0的原因。
return deferred.promise().then(function successCallback(data, status, headers, config) {
// Data might be a promise
$scope.articles = data;
//...
此外,您无需在控制器内返回。我不知道结果如何。
至于为什么看到你的文章,服务中可能会发生一些事情。不确定。
<强> EDIT1 强>
Page_Articles返回角度样式的承诺。这确实是一个阵列,我稍后会谈到。无论如何,这是它应该如何工作:
//Public page - List of articles
bordonHillControllers.controller('PageListCtrl', ['$scope', '$location' , 'Page_Articles', '$routeParams', function ($scope, $location, Page_Articles, $routeParams) {
$scope.pageId = $routeParams.pageId;
// Added var, the $promise attribute is what we want
var deferred = Page_Articles.get({ id: 1 }).$promise;
// After loading, assign the data
// I've removed the other params, they were adequate for jQuery promises
// Couldn't find the correct signature for $resource
deferred.then(function successCallback(data) {
$scope.articles = data;
if ($scope.articles.length == 1) {
$location.path('/article/' + $scope.articles[0].id);
}
alert(data.length)
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
return $scope.errorMessage = "Something went wrong!";
})
$scope.formatDate = function (date) {
var dateOut = new Date(date);
return dateOut;
};
}])
数组类型的原因是你可以像这样分配$资源(简写):
$scope.articles = Page_Articles.get({ id: 1 });
只要它没有完成,长度为零。解析后,阵列会自动填充。
编辑2:
速记是你看到文章的原因(这很棘手!)。您使用角度承诺(零长度数组)解决了延迟。然后将其分配给$scope.articles
。当它解决了文章自动出现时(速记的一个特征)。
是的,我明白了!
您可以优化的另一件事:您正在使用.get()
来查询数组。理想情况下,这是使用.query()
完成的。然后,您可以将.get()
用于单个项目(如在REST中)。我认为如果你需要,可以将params传递给查询。