如何告诉榆树外部DOM的变化 [英] how to tell elm about external DOM changes

查看:148
本文介绍了如何告诉榆树外部DOM的变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用elm 0.17.1并尝试与select2 javascript库(版本4.0.3)互操作,这是我的Main.elm:

I'm using elm 0.17.1 and trying to interop with select2 javascript library(version 4.0.3), here is my Main.elm :

port module Main exposing (..)

import Html exposing (Html,select,option,div,text,br)
import Html.App as App
import Html.Attributes exposing (id,value,width)
-- MODEL

type alias Model =
  {
     country : String
  }


-- UPDATE

type Msg =
      Select String

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    Select str -> (Model str,Cmd.none)


-- VIEW

view : Model -> Html Msg
view model =
  div[]
  [
    select [id "myselect"]
    [
     option [value "US"] [text "United States"],
     option [value "UK"] [text "United Kingdom"]
    ],
    text model.country
  ]

-- SUBSCRIPTIONS

port selection : (String -> msg) -> Sub msg

subscriptions : Model -> Sub Msg
subscriptions _=
  selection Select


port issueselect2 : String -> Cmd msg

-- INIT

init : (Model, Cmd Msg)
init =
  ({country=""},issueselect2 "myselect")

main : Program Never
main = App.program {init=init,view=view,update=update,subscriptions=subscriptions}

和javascript方:

and the javascript side :

$(document).ready(function()
     {
        var app=Elm.Main.fullscreen();
        app.ports.issueselect2.subscribe(function(id)
        {
           $('#'+id).select2().on('change',function(e)
           {
              app.ports.selection.send(e.target.value);
           });
        })
     })

现在当我选择一个国家/地区时,我的铬控制台中出现未捕获的类型错误,显示 domNode.replaceData 不是一个函数(它实际上是未定义的)。

Right now when I select a country an Uncaught type error in my chromium's console appears saying that domNode.replaceData is not a function(it is actually undefined).

问题是select2为DOM添加了一个跨度,而Elm不知道它,检查 domNode 显示Elm在更新文本时会尝试更新 span

The problem is that select2 adds a span to the DOM and Elm doesn't know about it, inspecting domNode reveals that Elm tries to update the span when it should update the text.

我想我需要效果,但我不知道如何在我的特定用例中使用它们。

I suppose I need effects but I don't know how to use them in my particular usecase.

如何解决我的问题?

我正在使用jquery 3的记录,我将我的elm程序编译成main.js并按以下顺序加载js文件:jquery.min.js,select2 .min.js,main.js然后是上面的js代码。

for the record I'm using jquery 3 , I compile my elm program into main.js and I load the js files in this order : jquery.min.js, select2.min.js,main.js then the above js code .

我无法用elm-reactor调试这个,因为它似乎只适用于榆树代码而不是js代码。

I couldn't debug this with elm-reactor because it seems to only work with elm code not js code.

推荐答案

为了解决这个问题,我做了一个这个例子展示了将任何第三方JavaScript技术集成到你的Elm应用程序中的所有核心思想。

To address this question I've made this example to demonstrate all the core ideas of integrating any third-party JavaScript technology in to your Elm app.

以下是规则:


  • 让Elm拥有st ate

  • 不要改变由Elm的
    视图生成的DOM

  • 你不需要 $(文件).ready(),如果Elm app控制
    初始化逻辑

  • 使用ports初始化和控制第三方代码

  • Let Elm to own the state
  • Do not mutate the DOM, produced by Elm's view
  • You don't need $(document).ready(), if Elm app controls the initialization logic
  • Use ports to initialize and control the third-party code

示例中的兴趣点:


  • index.js - JavaScript中的端口订阅设置和select2引导代码

  • index.js — port subscription setup in JavaScript and select2 bootstrap code

App.elm - 拥有select2的配置并订阅更改

App.elm — owns the configuration for select2 and subscribes to changes

该视图提供了所有jQuery魔术的容器:

The view provides a container for all the jQuery magic:

view : Model -> Html Msg
view model =
    div []
        [ text (toString model)
        , div [ id "select2-container" ] [] -- The container, where select2 will live
        ]

任何反馈都非常受欢迎,我愿意改善这个答案,如果你可以告诉我,缺少什么。

Any feedback is very welcome, I'm willing to improve this answer if you could tell me, what is missing.

这篇关于如何告诉榆树外部DOM的变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆