2015-08-29 79 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請求,直到第一個請求完成。所以我會檢查這些請求是否會在一段時間後停止,或者一直繼續,因爲這可能有助於縮小它的可能範圍。