强制组件从 Mithril.js 中的不同组件重绘

Forcing a component to redraw from a different component in Mithril.js

我有 2 个组件 - addProjectFormlistProjects。它们都是根模块中的嵌套组件。每当我使用表单添加项目时,我都希望它立即出现在列表中。

为此,我必须像这样将控制器实例传递给每个组件:

var RootComponent = {};

rootComponent.controller = function() {
     this.example = 'test variable';
}

rootComponent.view = function(ctrl) {
     return [
           m.component(addProjectForm, ctrl),
           m.component(listProjects, ctrl)
     ];
}

然后是 listProjects 组件,例如,如下所示:

var listProjects = {
     controller: function(root) {
          this.root = root;
     },
     view: function(ctrl) {
          console.log(ctrl.root.example);
     }
};

所以我一直在顶层调用方法,但我不太喜欢像这样向下传递控制器实例。还有其他方法吗?

我想这就是您要找的:

解决这个常见问题的新方法是使用 Facebook 开发的类似 Flux 的架构:

https://facebook.github.io/flux/

编写自己的调度程序并不容易。这是其他人与 Mithril 一起构建的示例:

https://gist.github.com/MattMcFarland/25fb4f0241530d2f421a

这种方法的缺点是使用 m.withAttr 会有些反 Flux,因为视图不应该直接写入调度程序范例中的模型。

您遇到的问题是按引用传递或按值传递之间的区别。在 JS 中,所有原始类型都是按值传递的。这就是为什么你不能直接传递字符串,因为它是在传递过程中被克隆的。您在这里有多种选择:

您可以使用 m.prop 并将变量向下传递给组件,m.props 将值存储在始终通过引用传递的函数中。

var RootComponent = {};

rootComponent.controller = function() {
     this.example = m.prop('test variable');

}

rootComponent.view = function(ctrl) {
     return [
           m.component(addProjectForm, ctrl.example),
           m.component(listProjects, ctrl.example)
     ];
}

如果变量是数组,无论如何都会通过引用传递。

第二个选项是将列表保留在根上下文中并向第二个组件添加回调。

var RootComponent = {};

rootComponent.controller = function() {
    var projects = this.projects = [];
    this.addProject = function(project) {
        projects.push(project);
    }

}

rootComponent.view = function(ctrl) {
    return [
        m.component(addProjectForm, {
            onsubmit: ctrl.addProject
        }),
        m.component(listProjects, ctrl.projects)
    ];
}