榆木+ Masonry.js

乔治

我正在尝试通过端口将Elm应用程序与Masonry.js集成在一起,但在尝试弄清楚如何获取Signal Html来触发告诉Masonry.js重绘视图的端口时遇到了麻烦。

我正在使用StartApp,但不确定如何从更新调用中获取视图已完成重新呈现的信号。

与Elm或更好的Elm解决方案可能更好地工作的替代库也将受到赞赏。

有关我要解决的整体问题的更多详细信息:我有一系列图像,并且想要以砖石格式(http://masonry.desandro.com/进行平铺它们由Elm中的对象列表表示,这些对象被转换为视图中的div列表(适当设置了背景图像),但是图像的大小不同,因此需要很好地平铺它们。我正在使用StartApp(http://package.elm-lang.org/packages/evancz/start-app/2.0.2/)抽象html的实际呈现。

乍得·吉尔伯特

您可以使用Elm中的端口与javascript通信,以便双向发布和订阅事件。让我们构建一个示例,其中以砖石布局显示图像列表,然后单击图像将其删除并触发砖石布局其余图像。

由于Elm应用程序将向javascript发送多种类型的事件,因此我们可以创建一个端口,该端口发送可随后对javascript进行操作的字符串。这些字符串将是我们可以在javascript中解释的命令,以便告诉砌体做某些事情,例如"initialize""imageRemoved"该端口还需要一个邮箱,我们可以从Elm内部向其发送消息。

masonryMailbox : Signal.Mailbox String
masonryMailbox =
  Signal.mailbox ""

port masonryCommands : Signal String
port masonryCommands =
  masonryMailbox.signal

由于您使用StartApp,您可以返回Effects你的update功能,让我们创建一个将邮件发送到该邮箱从两个函数StartApp初始化,并从内部update功能。

sendMasonryCommand : String -> Effects.Effects Action
sendMasonryCommand cmd =
  let
    task =
      Signal.send masonryMailbox.address cmd
        `Task.andThen` \_ -> Task.succeed NoOp
  in
    Effects.task task

您可以"initialize"StartAppinit函数期间发送命令,如下所示:

init =
  (initialModel, sendMasonryCommand "initialize")

update函数中,如果有RemoveImage String动作,我们可以向"imageRemove"javascript发送命令:

update action model =
  case action of
    NoOp ->
      (model, Effects.none)
    RemoveImage url ->
      let model' =
        { model
        | images = List.filter ((/=) url) model.images
        , message = "Removing image " ++ url
        }
      in (model', sendMasonryCommand "imageRemoved")

现在,我们需要连接事物的javascript端以侦听这些事件。如果javascript得到了命令"initialize",那么我们就可以砌砌。如果得到"imageRemoved"命令,我们可以告诉砌筑再次触发布局命令。

var app = Elm.fullscreen(Elm.Main);
app.ports.masonryCommands.subscribe(function(cmd) {
  var $grid = $('.grid')

  if (cmd === "initialize") {
    $grid.masonry({
      itemSelector: '.grid-item',
      percentPosition: true,
      columnWidth: '.grid-sizer'
    });

    $grid.imagesLoaded().progress( function() {
      $grid.masonry();
    });  
  } else if (cmd === "imageRemoved") {
    $grid.masonry();
  }
});

我们还可以连接端口以将事件发送回Elm。让我们添加示例,每次砌体完成渲染时都向Elm发送一条消息。首先,我们将创建一个名为的端口setMessage

port setMessage : Signal String

由于这是javascript将发布的端口,因此我们仅在Elm中定义函数签名,而不是函数本身。相反,当我们调用时,必须从javascript端为信号提供一个初始值Elm.fullscreen()javascript更改为:

var app = Elm.fullscreen(Elm.Main, { setMessage: "" });

现在,在处理该"initialize"命令的javascript块中,您可以连接砌体的layoutComplete功能,以向该新端口发送消息。

$grid.on("layoutComplete", function() {
  app.ports.setMessage.send("Masonry layout complete!");
});

为了从setMessageElm中端口使用这些消息,您需要执行一个SetMessage String操作,并且需要在StartApp inputs列表中映射信号您的StartApp初始化代码如下所示:

app =
  StartApp.start
    { init = init
    , view = view
    , update = update
    , inputs = [ Signal.map SetMessage setMessage ]
    }

我在几个要点中提供了所有这些的完整工作示例。这是包含Elm代码要点,这是包含html和javascript要点

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章