在寓言-elmish中,如何在渲染视图后触发命令?

时间:2018-10-05 15:45:49

标签: f# fable-f# elmish

我创建了一个应用程序,该应用程序下载一些数据并使用Google图表将其绘制到具有特定div的{​​{1}}上。

这在静态页面上可以正常工作。但是,当使用菜单在多个视图之间切换时,当切换回适当的视图时,我正努力重绘图表。

如果在更新模型时使用命令重绘图表,则请求失败,因为尚未呈现特定的Id

div的{​​{1}}阶段完成后,是否可以触发命令?还是重新绘制图表的更好方法?

下面的示例代码(不可运行,但应该直接易懂)。单击“获取数据”按钮可以正常工作,但是如果您随后又切换到另一页,则找不到重新绘制图表的方法。

View

HTML只是:

Model-View-Update

2 个答案:

答案 0 :(得分:4)

您可以使用Ref属性来检测何时安装了无状态React元素。

例如,这就是我在生产应用中使用的:

div [ Id "Chart1"
      Ref (fun element ->
          // Ref is trigger with null once for stateless element so we need to wait for the second trigger
          if not (isNull element) then
              // The div has been mounted check if this is the first time
              if model.IsJustLoaded then
                  // This is the first time, we can trigger a draw
                  dispatch DrawChart 
          )
 ]
    [ ]

另一种可行的方法是将div [ Id "Chart1" ] [ ]转换为有状态的React组件,并在调用componentDidMount时触发平局。

答案 1 :(得分:1)

在不看代码的情况下给出具体建议有些困难,但这是如何处理代码的一般思路。在您的鞋子中,我可能会使用Promise implementation from the Fable Powerpack,并按以下步骤进行设置:

  • 绘制图表的代码还没有绘制图表,它只是返回一个承诺,当解决该问题时,它将绘制图表。
  • 在视图函数中的div之后,立即使用this hack触发一些Java代码,这些代码将解决promise,从而触发draw()事件。 (或者,按照建议的in another answer to that question,将代码放在视图底部的script元素中,以便其执行不会阻止任何其他内容的渲染,然后在脚本中进行操作兑现承诺)。

对不起,这是如此含糊;如果看到您的代码,我也许可以提出更具体的建议。特别是,我不知道如何最好地处理兑现承诺:将其存储在模型中似乎是个坏主意(在不可变的数据模型中存储可变的内容……是的),但是我没有提出一个更好的主意。但是与承诺相关的某事似乎将是处理这种情况的最佳方法。