javascript - 在 Mithril 中使用 m.component() 时如何遍历 VDOM?

标签 javascript mithril.js

我是 Mithril 的新手,但对它强制执行良好编码模式和关注点分离的方式感到非常满意。引用这一点,我开始编码,大量使用 m.component()。

后来我读了 Mithril 文章“当 CSS 让你失望时”( http://lhorie.github.io/mithril-blog/when-css-lets-you-down.html ),它解释了如何编写 Transformer-Functions 来遍历和操作虚拟 DOM-Tree。编写几种横切关注点的绝妙概念。

但是当我尝试将此模式与包含组件的 VDOM 一起使用时,它不起作用,因为 m.component 返回一个组件而不是 VDOM 对象。检测组件没有帮助,因为此时尚未构建嵌入 View 。

现在我问自己,如何处理这个问题,或者我是否误解了一些根本性错误......

这里有几行代码显示了问题:

...

someComponent.view = function() {
return m('html', [
    m('body', [
        m('div', [
            m.component(anotherComponent)
        ])
    ])
};

...

// and now the traversal function from the mithril side
var highlightNegatives = function (root, parent) {
    if (!root) return root;
    else if (root instanceof Array) {
        for (var i = 0; i < root.length; i++) {
            highlightNegatives(root[i], parent);
        }
    } else if (root.children) {
        highlightNegatives(root.children, root);
    } else if (typeof child == "string" && child.indexOf("($") === 0) {
        parent.attrs.class = "text-danger";
    }
    return root;
};

highlightNegatives(someComponent.view()); // will not find the relevant elements in "anotherComponent"

其他人如何处理这个问题?

最佳答案

组件是在博客文章撰写后添加的。

您需要将组件转换为 vDOM 对象,然后才能将其包含在 View 中。请注意,我已经这样做了 2 次,一次是在 heightNegatives() 函数内,以便在我们遍历 vDOM 树时捕获组件,一次是在我们在 View 中调用它时的函数参数中。

您可以只包含组件标识符,而不调用 m.component(),除非您想向组件发送属性或其他选项:

myComponent
vs.
m.component( myComponent, {extraStuff: [1,2,3]}, otherStuff )

调用highlightNegatives() 时需要考虑这一点。

模板中无需包含 htmlbody。浏览器会为您完成此操作(当然,您也可以将它们包含在index.html中)

这是下面代码的一个工作示例: http://jsbin.com/poqemi/3/edit?js,output

var data = ['$10.00', '($20.00)', '$30.00', '($40.00)', '($50.00)']

var App = {
  view: function(ctrl, attrs) {
    return m("div.app", [
      m('h1', "My App"),
      someComponent
    ])
  }
}

var anotherComponent = {
  controller: function (){
    this.data = data
  },
  view: function (ctrl){
    return m('div.anotherComponent', [
      m('h3', 'anotherComponent'),
      ctrl.data.map( function(d) {
        return m('li', d)
      })
    ])
  }
}

var someComponent = {}
someComponent.controller = function (){ }
someComponent.view = function (ctrl) {
  return m('div.someComponent', [
      m('h2', 'someComponent'),
          highlightNegatives(anotherComponent.view( new anotherComponent.controller() ))
        ])
};

// and now the traversal function from the mithril side
var highlightNegatives = function (root, parent) {
    if (!root) return root;
    else if (root instanceof Array) {
      for (var i = 0; i < root.length; i++) {       
        // when you encounter a component, convert to VDOM object
        if (root[i].view) {
          highlightNegatives(root[i].view( new root[i].controller() ))
        }else{
          highlightNegatives(root[i], parent);
        }
      }
    } else if (root.children) {
        highlightNegatives(root.children, root);
    } else if (typeof root == "string" && root.indexOf("($") === 0) {
          parent.attrs.class = "text-danger";
    }
    return root;
};

m.mount(document.body, App)

//Calling this function after the App is mounted does nothing.
//It returns a vDOM object that must be injected into the someComponent.view
//highlightNegatives(someComponent.view()); // will not find the relevant elements in "anotherComponent"

关于javascript - 在 Mithril 中使用 m.component() 时如何遍历 VDOM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31574214/

相关文章:

javascript - 将 json 对象属性提取到数组中的简单方法?

html - 如何在 Mithril 中将字符串转换为 HTML 元素?

javascript - 无需比较或重绘所有内容即可安装

javascript - 禁用按钮,直到完成所有必填字段

javascript - 如何 json.stringify() 一个字符串

javascript - 如何使用 styled-components 更改其他组件中单个组件的样式?

javascript - 我可以使用 jQuery 和 AJAX 来执行在同一文件中编写的 php 代码吗?

javascript - Mithril - 渲染动态内容

javascript - Mithril JS : Routing a component inside top level component

javascript - 使用背景 :true? 时如何在 MithrilJS 中使用 m.request 的值