2015-08-29 48 views
0

我刚开始学习mithril,并且正在尝试编写一个与RESTful API交互的简单前端。但是,当我在浏览器中加载时,浏览器每秒发出30次GET请求到'/ posts'!我不确定这是否是我的代码错误或mithril工作原理......如何在整个代码中使m.request发出请求一次,或者更新Post.list?m.request问题太多请求

var Post = { 
    model: function(data) { 
    data = data || {}; 
    this.id = m.prop(data.id); 
    this.text = m.prop(data.text); 
    this.rating = m.prop(data.rating); 
    this.created_at = m.prop(data.created_at); 
    this.url = m.prop(data.url); 
    this.title = m.prop(data.title); 
    this.user_id = m.prop(data.user_id); 
    }, 
    list: function() { 
    return m.request({ 
     method: "GET", 
     url: "/posts/", 
     type: Post.model 
    }); 
    } 
} 
var PostIndex = { 
    controller: function() { 
    this.posts = Post.list(); 
    }, 
    view: function(ctrl) { 
    return [ 
     m("table.table", [ m("tbody", [ 
     ctrl.posts().map(function(post) { 
      return m("tr", [ 
      m("td.heading", { onclick: m.route('/posts/' + post.id) }, [ 
       post.title, 
       m("small", post.url) 
      ]), 
      m("td", [ m("small", post.user + ": " + post.created_at) ]) 
      ]); 
     }) 
     ])]) 
    ]; 
    } 
}; 
+0

m.request是基本的AJAX。 “/ posts /”的网址没有给你一个帖子列表。你需要“GET”一个文件,而不是目录。米索莉希望这个文件是一个JSON文件。该文件也可以是您的后端(php/python/perl/javascript)返回JSON的脚本。如果它不返回JSON,则有方法将响应转换为JSON。首先阅读AJAX,然后阅读m.request上的Mithril文档:http://lhorie.github.io/mithril/mithril.request.html –

+0

是的,我明白了;我还在sinatra中运行后端Web API,它在'/ posts /'中为JSON中的帖子提供数组。我的问题不是解析JSON或显示帖子的内容,而是关于为什么m.request每秒钟触及服务器<30次。 –

+0

对不起,很难告诉开发人员如何使用一段代码。我不能在没有看到更多代码的情况下回答你的问题,但是AFAIK唯一可以进行这么多调用的Mithril是在创建列表的视图中使用了m.request,并且我没有在上面的代码中看到这个错误。 sinatra是否提供JSON“文件”,或者是一个一个一个的数组?是否有多个帖子,每个都是JSON格式,或者是一个包含所有帖子的JSON数组 - 正如m.request所期望的那样? sinatra是否可能在吐出流中的帖子?我很抱歉,我对sinatra或您正在使用的图书馆知之甚少。 –

回答

1

Mithril在内部使用了一种叫做虚拟DOM的东西。它的工作方式是存在内存模型的DOM,每当模型对象中的某个对象发生更改或用户与该页面进行交互时,该模型就会更新。基本上,所有的时间。 这一切都发生在内存中,并被优化为非常快速地工作。每次重新创建虚拟DOM时,它都会将自身与实际DOM进行比较,以查看是否有任何差异。如果有什么不同的话,那么Mithril才会更新实际的DOM。这是使秘银如此之快的一部分。

我不是很积极,但是m.request可能被视图函数调用,而视图函数会一直触发(更新虚拟DOM)。

ctrl.posts().map(function(post) { 
     return m("tr", [..... 

如果是这样的话,那么这里发生了什么如下: ctrl.posts() - > Post.list() - > m.request

一个可能的解决办法是将存储m.request的结果一旦完成执行,然后与其他地方的存储值相关联。 你可以改变你的控制器代码以下:

controller: function() { 
    this.posts = m.prop([]) 
    Post.list().then(this.posts, console.log) 
}, 

这首先初始化this.posts与getter/setter函数,它会返回一个空的列表了。 然后它调用m.request函数,它将一次发送GET请求。一旦请求结束,结果将传递给“then”函数。 “然后”将函数作为参数:第一个 - 如果前一个函数成功,该怎么办?第二个 - 如果失败,该怎么做。无论哪种方式,传递的函数都会自动接收前一个函数的结果,因此不需要明确指定。由于this.posts现在是一个通过传递参数设置的函数,因此会自动为m.request调用的结果设置this.posts。

在此更改之后,当在视图函数中调用ctrl.posts时,将调用存储在变量中的内容,而不是每次发送垃圾邮件m.request。

我目前正在学习秘银自己,并与它度过美好的时光。我并不是积极的,我所描述的是这里发生的事情,但听起来像这样。如果我的建议没有帮助,那么可能是您的代码在每次调用ctrl.posts()时发送AJAX请求,直到第一个请求完成。所以我会检查这些请求是否会在一段时间后停止,或者一直继续,因为这可能有助于缩小它的可能范围。