gpt4 book ai didi

masonry - 榆树 + Masonry.js

转载 作者:行者123 更新时间:2023-12-01 16:03:19 28 4
gpt4 key购买 nike

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

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

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

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

最佳答案

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

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

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

port masonryCommands : Signal String
port masonryCommands =
masonryMailbox.signal

由于您使用的是 StartApp,您可以在 update 函数中返回 Effects,所以让我们创建一个函数,将消息发送到此邮箱来自 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

您可以在 StartApp init 函数中发送 "initialize" 命令,如下所示:

init =
(initialModel, sendMasonryCommand "initialize")

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

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",那么我们就可以连接 masonry 了。如果我们得到 "imageRemoved" 命令,我们可以告诉 masonry 再次触发布局命令。

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。让我们在每次 masonry 完成渲染时向 Elm 发送一条消息来添加示例。首先,我们将创建一个名为 setMessage 的端口。

port setMessage : Signal String

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

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

现在,在处理 “initialize” 命令的 javascript block 中,您可以连接 masonry 的 layoutComplete 函数以将消息发送到这个新端口。

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

为了在 Elm 中使用来自 setMessage 端口的这些消息,您需要一个 SetMessage String 操作,并且您需要将信号映射到 StartApp inputs 列表。您的 StartApp 初始化代码将如下所示:

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

我在几个要点中提供了所有这些的完整工作示例。这是一个 gist containing the Elm code这是一个gist containing the html and javascript .

关于masonry - 榆树 + Masonry.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35738808/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com