【问题标题】:How to implement Infinite Scrolling using Node.js, Angular.js and Firebase?如何使用 Node.js、Angular.js 和 Firebase 实现无限滚动?
【发布时间】:2017-03-26 17:07:25
【问题描述】:

更新 8:

代码:

<% include ../partials/header %>


<script src="https://www.gstatic.com/firebasejs/3.5.2/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/firebase-util/0.2.5/firebase-util.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/1.1.4/angularfire.min.js"></script>

<script>


  var config = {
     info
  };

  firebase.initializeApp(config);

    var fb = firebase.database().ref("posts/fun");

    var app = angular.module('app', ['firebase']);

    app.controller('ctrl', function ($scope, $firebaseArray, $timeout) {

        $scope.data = [];
        var _start = 0;
        var _end = 4;
        var _n = 5;

        $scope.getDataset = function() {

            fb.orderByChild('id').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) {

                $scope.data.push(dataSnapshot.val());
                console.log("THE VALUE:"+$scope.data);

            });

            _start = _start + _n;
            _end = _end + _n;

        };


        $scope.getDataset()

    });

    // Compile the whole <body> with the angular module named "app"
    angular.bootstrap(document.body, ['app']);


</script>


<div class ="containerMarginsIndex">

   <div ng-controller="ctrl">

            <div class="fun" ng-repeat="d in data">
                <h3 class="text-left">{{d.title}}</h3>
                    <div class = "postImgIndex">
                        <a href="details/{{d.id}}" target="_blank">
                            <img class= "imgIndex" ng-src="/images/uploads/{{d.image}}" >
                        </a>
                    </div> 
                <div class="postScore">{{d.upvotes - d.downvotes}} HP</div>
            </div>

    </div>

</div>

<% include ../partials/footer %>

情况:

好的,我已经重新设计了我的 Firebase 数据库架构并更改了 Firebase 规则。

我现在确定 Firebase 函数返回一个值(它已记录在控制台中)。

但我仍然收到以下错误:

这个 HTML:

    <div class="fun" ng-repeat="d in data">
        <h3 class="text-left">{{d.title}}</h3>
            <div class = "postImgIndex">
                <a href="details/{{d.id}}" target="_blank">
                    <img class= "imgIndex" ng-src="/images/uploads/{{d.image}}" >
                </a>
            </div> 
        <div class="postScore">{{d.upvotes - d.downvotes}} HP</div>
    </div>

在 RENDERED 后被此替换:

<!-- ngRepeat: d in data --> == $0

我做错了什么?

【问题讨论】:

标签: javascript angularjs node.js firebase firebase-realtime-database


【解决方案1】:

它没有显示在您的视图中,因为您在 $scope 上没有任何内容,并且您没有使用 {{}} 插入数据。请参阅以下更改:

data 分配给要在视图中使用的$scope 变量:

$scope.data = [];
var _start = 0;
var _end = 4;
var _n = 5;
var getDataset = function() {
  fb.orderByChild('time').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) {
  $scope.data.push(dataSnapshot.val());
});

_start = _start + _n;
_end = _end + _n;

而您的观点,使用ngRepeat{{}} 进行插值:

<div class ="containerMarginsIndex">

          <div class="fun" ng-repeat="d in data">
            <h3 class="text-left">{{d.title}}</h3>
            <div class = "postImgIndex">
            <a href="details/{{post.id}}" target="_blank">
                <img class= "imgIndex" src="/images/uploads/{{post.image}}" >
            </a>
            </div> 
            <div class="postScore">({{d.upvotes - d.downvotes}}) HP</div>
        </div>

</div>

【讨论】:

  • 尚未工作,但正在取得进展。你能看看更新 6 吗?
  • @Coder1000 - 验证您的数据变量是否已实际填充。注释意味着data 是一个空数组。
  • 我刚刚查过了。 getDataSet() 似乎永远不会被调用。更糟糕的是:我尝试直接调用它:$scope.getDataset() 仍然:什么也没发生......
  • @Coder1000 -- 你的控制台语句是否在getDataset 测试中被调用? (console.log("4")?
  • 请再看一下更新7,我刚刚修改了它:)
【解决方案2】:

您需要包含$scope.$apply(),因为滚动事件在 Angular 的上下文之外执行。

此外,事件侦听器应该在您的控制器内,以便可以访问作用域内的 more 函数。

这是一个更新的小提琴:

https://jsfiddle.net/xue8odfc/2/

我会说 Angular 无法解决 {{post.image}} 等的问题是由于您引用的库之间的不兼容。我建议使用工作 jsfiddle 中的版本进行测试:

<script src="https://cdn.firebase.com/js/client/2.0.3/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/firebase-util/0.2.5/firebase-util.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.1/angular.min.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/1.1.4/angularfire.min.js"></script>

【讨论】:

  • ignoreScrollRetrieve 未定义(…)
  • 我已经更新了链接。请再试一次 - jsfiddle.net/xue8odfc/2
  • 我还添加了一个变量,以避免浏览器在等于比较时出现任何错误。只是为了安全
  • angular.js 变量仍然没有被加载:/
  • 在我的小提琴或你的代码中?控制台中有任何错误消息吗?
【解决方案3】:

在控制器中添加滚动监听器。函数more 确实不存在,但是你有一个$scope.more 方法。

app.controller('ctrl', function ($scope, $firebaseArray, $timeout) {

    // ORDERED BY TIME:
    var ref = firebase.database().ref("posts/fun");
    var scrollRef = new Firebase.util.Scroll(ref, "time");
    $scope.posts = $firebaseArray(scrollRef);
    scrollRef.scroll.next(5);

    // AS DATA APPEARS IN DATABASE ORDERED BY TIME:
    ref.once('value', function(snap) {
        $scope.rawdata = snap.val();
        $scope.$apply();
    });

    $scope.more = function() {
       scrollRef.scroll.next(5);
    };

    // Add scroll listener
    window.addEventListener('scroll', function() {
      if (window.scrollY === document.body.scrollHeight - window.innerHeight) {
        $scope.$apply($scope.more);
      } 
    });
});

请注意,我在$scope.$apply 内调用$scope.more,以便在调用结束时消化范围。实际上,窗口滚动事件上的 JS 侦听器超出了 Angular 生命周期,因此我们需要手动$digest Angular 的范围来更新其所有观察者并更新 HTML。如果您想了解更多信息,请在线搜索$scope.$apply

关于您的第一个问题

您的 Angular 应用程序未启动,因为 Angular 从未初始化。为此,您需要同步加载它并使用 ng-app 指令,或者如果您不想对代码进行任何更改,您只需在模块和控制器定义后添加以下行:

// Compile the whole <body> with the angular module named "app"
angular.bootstrap(document.body, ['app']);

【讨论】:

  • 我认为你的代码有效,但我的角度变量仍然没有被它们的实际值替换:/你知道是什么原因造成的吗? (我对 Angular.js 完全陌生)
  • @Coder1000 实际上我已经更新了关于您的第一个问题的答案。在 body 或包含 ng-controller 的元素上尝试 angular.boostrap
  • angular.js:68 未捕获的错误:[jqLit​​e:nosel] jqLit​​e 不支持通过选择器查找元素!请参阅:docs.angularjs.org/api/angular.element(…)
  • @Coder1000 尝试将angular.elment('body') 替换为document.body,即angular.bootstrap(document.body, ['app']);
  • angular.js:68 未捕获的错误:[$injector:modulerr] 无法实例化模块应用程序,原因是:错误:[$injector:modulerr] 无法实例化模块 firebase,原因是:错误:[$ injector:nomod] 模块“firebase”不可用!您要么拼错了模块名称,要么忘记加载它。如果注册模块,请确保将依赖项指定为第二个参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-18
  • 2017-08-16
  • 2014-05-17
  • 2018-07-30
  • 1970-01-01
  • 2022-06-16
  • 1970-01-01
相关资源
最近更新 更多