Mithril 的新手,但真的很喜欢它。几周前,我使用React和Redux编写了用于状态管理的演示应用程序。我还使用了一个库来将两者连接起来,但是它们都能正常工作,并且可以在http://curiousercreative.com/demos/bankDemo/上看到。在阅读了 Mithril 并喜欢我所读的内容之后,我决定将同一个演示应用程序翻译成 Mithril + Redux,但是我似乎无法让 Mithril 安装的组件来更新/重新绘制,因此更新了我的Redux商店(状态)从未反射(reflect)在用户界面中。从我的应用程序的js / app.js行〜144-162中,我安装了Redux回调和两个顶级Mithril组件,并通过了我们的状态。

// redraws Mithril whenever an action is dispatched
    store.subscribe(function () {
      console.log('happening');
      m.redraw.strategy('all');
      m.redraw(true);
    });

// Render Mithril
    // content
    m.mount(
      document.getElementById('content'),
      m.component(App, store.getState())
    );

    // nav
    m.mount(
        document.getElementById('navContainer'),
        m.component(Nav, store.getState())
    );

如果您在http://curiousercreative.com/demos/bankDemo-mithril/上打开控制台,则每次单击新链接(都会更改哈希值,从而更新Redux状态存储)时,您会注意到一个日志条目。您还会在上面的代码中注意到,每次发生日志时,都应该强制重绘 Mithril ,但是UI不会改变。将其行为与上面的React演示应用程序进行比较。在应用程序的js / components.js文件中,我们的两个顶级组件将此状态对象作为参数,并将其传递给其子组件。
  var App = {
    controller: function (args) {
      this.activePageId = args.activePageId;
      this.accounts = args.accounts;
      ...

  var Nav = {
    controller: function (args) {
      this.activePageId = args.activePageId;
      this.accounts = args.accounts;
      ...

为什么 Mithril 不重绘?

最佳答案

问题在于,初始化时getState()仅被调用一次,因此该组件将始终使用对同一原始静态数据存储快照的引用进行重绘。

安装顶级组件后,将执行其 Controller ,并通过访问 Controller 和任何传入的参数来编译和构建其 View 。 Controller 在初始化时仅执行一次-当重绘触发时, View 函数将重新执行。这意味着可以向嵌套组件传递其 View 将可以访问的新参数,但是已装入(顶级)组件必须绑定(bind)其参数,并且由于它们不是任何 View 本身的后代,因此必须确定自己的逻辑以用于更新引用。

查看您的代码时,一些想法会跳出来:

您可以在mount中传入getState方法(无需调用它)-Mithril是在 View 中使用函数进行数据输入和检索的强烈支持者(如m.prop所示,它是用于简单模型管理的内部工具):

var component = {
  view : function( ctrl, accessor ){
    return m( 'p', accessor().value )
  }
}

m.mount( document.body, m.component( component, store.getState ) )

动态选择器属性倾向于在属性映射中更好地读取。请注意,您可以将选择器字符串类与属性映射类结合使用。 Controller 中声明的activePage函数看起来像是关注点分离,但是由于 View 需要具有该特定方法的钩子(Hook),因此该函数显式地用于生成className,并且逻辑是如此简单,因此可以显着降低复杂性并通过将逻辑直接放在 View 中来提高可读性:
m('div.page', {
  id    : args.id,
  class : args.id === args.activePageId ? 'active' : ''
}, /* ... */ )

请注意,您无需将虚拟DOM子级显式包装在数组中:可以按顺序包含它们。实际上,这意味着方括号在Mithril虚拟DOM语法中是多余的:
m( '.parent',
  m( '.child1' ),
  m( '.child2' )
)

关于javascript - 通过外部状态更改(Redux)更新/重绘Mithril组件 View ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33716022/

10-11 12:32