使用外部状态更改更新/重绘Mithril组件视图(Redux)

时间:2015-11-15 03:18:33

标签: javascript redux mithril.js

秘银的新手,但我真的很想喜欢它。我几周前使用React和Redux编写了演示应用程序来进行状态管理。我还使用了一个库连接这两个,但它都可以工作,可以在http://curiousercreative.com/demos/bankDemo/看到。在阅读了Mithril并喜欢我阅读的很多内容后,我决定将相同的演示应用程序翻译成Mithril + Redux,但我似乎无法将我的Mithril安装组件更新/重绘,因此更新到我的Redux商店(州)并未在UI中反映出来。从我的应用程序的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演示应用程序进行比较。在app的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;
      ...

为什么没有秘银重绘?

1 个答案:

答案 0 :(得分:2)

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

当安装了顶级组件时,它们的控制器执行,它们的视图被编译和构建,可以访问控制器和任何传入的参数。控制器在初始化时只执行一次 - 当重绘触发时,视图函数被重新执行。这意味着嵌套组件可以传递它们的视图可以访问的新参数,但是挂载(顶层)组件的参数是绑定的,并且因为它们本身不是任何视图的后代,所以它们必须确定它们自己的逻辑。更新参考文献。

在查看代码时会跳出一些想法:

你可以在mount中传递getState方法(不调用它) - Mithril是在视图中使用函数进行数据输入和检索的一个伟大的支持者(如m.prop所示,一个内部工具对于简单的模型管理):

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

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

动态选择器属性倾向于在属性映射中更好地读取。请注意,您可以将选择器字符串类与属性映射类组合使用。在控制器中声明的activePage函数看起来像是关注点的分离,但由于视图需要有一个特定方法的钩子,因此该函数显式用于生成className,并且逻辑非常简单,你' d通过将该逻辑直接放在视图中,显着降低了复杂性并提高了可读性:

m('div.page', {
  id    : args.id,
  class : args.id === args.activePageId ? 'active' : ''
}, /* ... */ )

请注意,您不需要在数组中显式包装虚拟DOM子项:您可以按顺序包含它们。实际上,这意味着方括号在Mithril虚拟DOM语法中是多余的:

m( '.parent',
  m( '.child1' ),
  m( '.child2' )
)