AngularJS为包含对象的数组返回长度0

时间:2016-02-18 11:27:34

标签: angularjs json api

我正在尝试根据该页面可用的文章数量动态设置页面类型。所以,如果我有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>'
)

一切正常,我收到了2篇文章(这是我为这个页面设置的数量)但长度仍为0; i am getting an array of json object from the service

1 个答案:

答案 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传递给查询。