如何在Elm中实现无限滚动?

时间:2016-11-19 08:57:23

标签: javascript elm

我尝试为我的应用实现无限,并决定以下列方式执行此操作。这里从index.html中提取的代码将Elm应用程序绑定到特定节点,并定义了一些将在滚动事件上触发的代码:

(function() {
        
        var loadMore = function () {
          return $(window).scrollTop() === $(document).height() - $(window).height() 
        };

        var node  = document.getElementById('main');
        var myApp = Elm.Main.embed(node);

        $(window).bind('scroll', function () {
          var isBottom = loadMore();
          myApp.ports.scroll.send(isBottom);
        });

      })();

我认为它能满足我的需要,但我并不是百分百确定。

我不明白的部分是如何在Elm代码中处理这个问题。 我目前的方法(不起作用)如下。我提供它只是为了让我的意图更清楚我想要实现的目标。

-- SUBSCRIPTIONS
port scroll : (Bool -> msg) -> Sub msg

subscriptions : Model -> Sub Msg 
subscriptions model = 
  scroll Scroll

1 个答案:

答案 0 :(得分:1)

为了使用方法实现无限滚动,我选择了你需要的东西。我将高度概述正在发生的事情,主要组件是什么以及如何将它们组合在一起,然后深入研究一些代码。

抽象地说我需要遵循以下内容:

  • 我需要以某种方式对浏览器说我对scroll事件
  • 感兴趣
  • 发生此事件时,我需要触发一些代码。

如何说我对scroll个活动感兴趣的浏览器?

因为当前在Elm中滚动事件的实现要么不存在要么难以使用我决定使用 jQuery 来处理这些事件。

您可以在index.html查看我使用的所有代码。它没有什么必要的东西:

  1. 它加载Elm app并将其附加到页面上的某些DOM元素

  2. 将回调绑定到每次都会触发的scroll事件 发生此事件

    (function($) {
    
      var loadMore = function () {
        return $(window).scrollTop() === $(document).height() - $(window).height() 
    };
    
      var node  = document.getElementById('main');
      var myApp = Elm.Main.embed(node);
    
      $(window).bind('scroll', function () {
        var isBottom = loadMore();
        myApp.ports.scroll.send(isBottom);
      });
    
    })(jQuery);
    
  3. 我想提请你注意这句话:

    myApp.ports.scroll.send(isBottom);
    

    以下是我将一些数据发送到Elm世界的方式。

    myApp只是变量的名称,它包含对Elm应用程序的引用,这里没什么特别的。

    ports只是您必须使用的关键字才能实现此类事情。

    scroll这是将在Elm的一侧调用的函数名称。它由你定义(稍后我会告诉你如何做到这一点)

    send是必修部分。这是您向Elm app发送数据的方式。

    现在我需要做的就是以某种方式在Elm的方面收到这些数据。

    再次,高级概述。现在数据正在向我的Elm应用程序前进,我需要做的就是订阅这个事件(我们没有在Elm中回调,我们有订阅:))

    我是按照以下步骤完成的。我创建了名为Ports的模块,其中包含以下内容:

    port module Ports exposing (..)
    
    port scroll : (Bool -> msg) -> Sub msg
    
    如果您希望能够从榆树世界以外的国家/地区检索数据,则必须在port关键字之前使用

    module关键字。

    接下来,我在App.elm中导入此模块,这实际上是一些根级模块(主协调节点)。我只需要添加这一行:

    import Ports exposing (..)
    

    接下来,我需要在我的subscriptions中定义App.elm,如下所示:

    subscriptions : Model -> Sub Msg 
    subscriptions model = 
      scroll Scroll
    

    基本上我订阅特定事件,当此事件发生时,将调度特定Msg

    我需要很少的其他东西才能使整个事情发挥作用:

    • 我需要在Scroll数据类型中加入Msg条消息

    • update函数

      中处理此案例

      输入消息   = NoOp   | Scroll Bool

    正如您所看到的,我在值构造函数Scroll中指出我期望布尔值

    当然还有update功能。根据{{​​1}}是或否,我会触发一些代码来加载更多文章,例如。

    pos