AngularJS:来自服务的函数在 ng-infinite-scroll 指令中不起作用

AngularJS: function from service don't work in ng-infinite-scoll directive

我想使用 ng-infinite-scroll (https://sroze.github.io/ngInfiniteScroll/)。但是当我想从我的服务调用函数(注入控制器)时,什么也没有发生(这个函数不会触发)。当我不是从服务而是从控制器的 $scope 调用函数时 - 一切正常。如何从无限滚动指令中的注入服务调用函数?

我的HTML结构:

<div class="col-xs-12 publications-container" ng-controller="showPublicationsCtrl">
    <h3 class="publ-heading">Proposed Publications</h3>
    <ul class="list-group" infinite-scroll="publicationsFactory.getPublications()" infinite-scroll-disabled='publicationsFactory.busyLoadingData'>
      <li ng-repeat="publication in publications" class="list-unstyled list-group-item" ng-cloak>
        <p class="text-warning">Author: <i>{{publication.author}},   {{publication.timestamp | date: 'MMM. d, y'}}</i></p>
        <p ng-text-truncate="publication.text" ng-tt-words-threshold="3">{{publication.text}}</p>
        <p class="text-muted">Channels: <i>{{publication.channels.join(", ")}}</i></p>
      </li>
    </ul>
  </div>

我的showPublicationsCtrl控制器:

twitterApiApp.controller("showPublicationsCtrl", ['publicationsFactory', '$scope', function (publicationsFactory, $scope) {
  publicationsFactory.getPublications();
  $scope.publications = publicationsFactory.publications;
}]);

我的 publicationsFactory 服务:

angular.module('twitterApiApp').factory('publicationsFactory', ['$http', function($http) {
  var publicationsFact = {};
  publicationsFact.publications = [];
  publicationsFact.busyLoadingData = false;

  publicationsFact.getId = function() {
publicationsFact.id = publicationsFact.publications.length > 0 ?
                      publicationsFact.publications[publicationsFact.publications.length-1]['id'] : 0;
  };

  publicationsFact.getPublications = function () {
    console.log("Triggered");
    if (publicationsFact.busyLoadingData) return;
    publicationsFact.busyLoadingData = true;
    publicationsFact.getId();
    $http.get("/Publications?id_gte=" + publicationsFact.id + "&_limit=2").then(function(response) {
      for (var i = 0; i < response.data.length; i++) {
        publicationsFact.publications.push(response.data[i]);
      };
    });
    publicationsFact.busyLoadingData = false;
  };
  return publicationsFact;
}]);

如果我在我的控制器中创建一些函数,例如 $scope.myFunction 然后在 HTML 结构中我将 infinite-scroll 属性分配给 myFunction() 该函数将成功执行.所以,我认为我在控制器中注入服务的方式可能存在一些错误。但是除了 ng-inginit-scroll 之外的其他一切都按计划工作。

infinite-scroll 绑定到 $scope.publicationsFactory :

<ul class="list-group" infinite-scroll="publicationsFactory.getPublications()" infinite-scroll-disabled='publicationsFactory.busyLoadingData'>

但是 publicationsFactory 在您的范围内不可用,您必须像这样公开它:

twitterApiApp.controller("showPublicationsCtrl", ['publicationsFactory',  '$scope', function (publicationsFactory, $scope) {
    // Expose publication factory
    $scope.publicationsFactory = publicationsFactory;

    publicationsFactory.getPublications();
    $scope.publications = publicationsFactory.publications;
}]);

如何使用 Factory

检索到的最新出版物更新 $scope.publications

您的工厂可以 return 使用最新出版物解决的承诺,像这样更改您的代码:

angular.module('twitterApiApp').factory('publicationsFactory', ['$http', '$q', function($http, $q) {
    var publicationsFact = {};
    publicationsFact.publications = [];
    publicationsFact.busyLoadingData = false;


    publicationsFact.getId = function() {
        publicationsFact.id = publicationsFact.publications.length > 0 ?
            publicationsFact.publications[publicationsFact.publications.length - 1]['id'] : 0;
    };

    /**
     * Get latest publications
     * @returns {object} A promise
     */
    publicationsFact.getPublications = function() {
        var deferred = $q.defer();

        console.log("Triggered");
        if (publicationsFact.busyLoadingData) return;
        publicationsFact.busyLoadingData = true;
        publicationsFact.getId();
        $http.get("/Publications?id_gte=" + publicationsFact.id + "&_limit=2").then(function(response) {
            for (var i = 0; i < response.data.length; i++) {
                publicationsFact.publications.push(response.data[i]);
            };
            // Resolve promise with updates publications list
            deferred.resolve(publicationsFact.publications);
        }, function(error) {
            // Reject promise with error message
            deferred.reject(error.message);
        });
        publicationsFact.busyLoadingData = false;

        // Return promise
        return deferred.promise;

    };
    return publicationsFact;
}]);

然后,在你的控制器中:

twitterApiApp.controller("showPublicationsCtrl", ['publicationsFactory',  '$scope', function (publicationsFactory, $scope) {
    // Expose publication factory
    $scope.publicationsFactory = publicationsFactory;

    publicationsFactory.getPublications()
    .then(function(results) {
        $scope.publications = results;
    });
}]);    

您应该将此行添加到您的 ctrl 中:

$scope.getPublications = publicationsFactory.getPublications;

然后从视图中调用该 ctrl 函数。 这样,您将对服务功能的引用绑定到视图中可用的控制器范围。

编辑:另一种选择是将整个服务绑定到 ctrl 属性,正如其他人已经建议的那样