如何使用 JSON 源创建 Mithril.js SPA?

How to create Mithril.js SPA with JSON source?

我正在尝试使用 Mithril.js 制作 SPA(单页应用程序)。 到目前为止,我已经找到了很好的教程here, and of course on Mithril homepage,但仍然无法实现两者的结合。

这是 Dave 指南中修改后的工作示例...

function btn(name, route){
  var click = function(){ m.route(route); };
  return m( "button", {onclick: click}, name );
}
function Page(content){
  this.view = function(){
    return [         
      m("page", 
        m("span", Menu.menu()) 
      ) 
      , m("div", content)
    ];
  }
}
var Menu = { 
  menu: function(){
    return [
      btn("Home",   "/home")
    , btn("About",  "/about")
    ];
  }
};
var page_Home =  new Page("The home of the Hobbits. Full of forests and marshes.");
var page_About = new Page(["The blighted home of Sauron. Scenic points of interest include:"]);

  m.route(document.body, "/home", {
    "/home": page_Home,
    "/about": page_About
  });

我的 JSON 文件:

[
 {
  "id":1,
  "title": "Home",
  "url": "/home",
  "content":"This is home page"
 },{
  "id":2,
  "title": "About",
  "url": "/about",
  "content":"This is about page"
 },{
  "id":3,
  "title": "Galery",
  "url": "/galery",
  "content":"This is gallery page"
 }
]

以及我将以上两者结合起来的努力:

//model
var PageSource = {
  list: function() {
    return m.request({method: "GET", url: "pages.json"});
  }
};
var pages = PageSource.list();

var App = {
  //controller
  controller: function() {
    return {
      menu: pages
    , rotate: function() { pages().push(pages().shift()); }
    , id: m.route.param(pages.url)
    }
  },

  //view
  view: function(ctrl) {
    return  [
      m("header"
        , m("h1", "Page Title")
        , m("span",
            ctrl.menu().map(function(item) { 
              var click = function(){ 
                console.log (item.url);
                m.route(item.url); 
              };               
              return [
                  m("button", {onclick: click}, item.title)        
              ];
            })
          )
        , m("hr")
       )
    ,  m("button", {onclick: ctrl.rotate}, "Rotate links" )
    ,  m("p", ctrl.content ) //CONTENT
    ];
  }
};

//initialize
  m.route(document.body, "/home", {
    "/:id": App
  });

最后,问题是: - "How can I retrieve data from JSON file and display it in div based on selected button (routing)?" - "When I use m.route my entire view refreshes, but I only want to reload changed div. How?" 请帮忙,因为到目前为止我真的很喜欢 mithril.js

你很接近。

  1. 您的路由器似乎配置了两次,其中后一个声明将覆盖第一个。使用 m.route 声明您的路线一次,并在其他代码声明之后。

  2. 当您尝试在 App 视图中引用 ctrl.content 时,它将是未定义的,因为您尚未在 App 控制器中定义内容 属性。添加任何你想要的内容 属性 到 App controller returns.

  3. 的对象中

多亏了@dcochran,我才做到了这一点:

//model
var PageSource = {
  list: function() {
    return m.request({method: "GET", url: "pages.json"});
  }
};
var pages = PageSource.list();
var id = m.prop()
  , url = m.prop()
  , title = m.prop()
  , content = m.prop();

var App = {
//controller
  controller: function() {
    return {
      menu: pages
    , rotate: function() { pages().push(pages().shift()); }
    }
  },

//view
  view: function(ctrl) {
    return  [
      m("header"
        , m("h1", "Page title")
        , m("span",
            ctrl.menu().map(function(item) { 
              return [ btn(item.title, item.url) ];
              function btn(name, route){
                var isCurrent = (url === route);
                var click = function(){ 
                  //m.route(route); 
                  id = item.id;
                  url = item.url; 
                  content = item.content;
                  title = item.title;
                };
                return m(
                  "button"+(isCurrent ? ".active" : ""), 
                  {onclick: click}, 
                  name
                );
              }
            })
          )
        , m("hr")
       )
    ,  m("button", {onclick: ctrl.rotate}, "Rotate links" )
    ,  m(".page", content )
    ];
  }
};
//initialize
m.route.mode = "hash";
m.route(document.body, "/home", { 
  "/:url": App
})