2014-06-18 147 views
5

我目前停留在一個相當「大」的問題,我會盡量做到儘可能清晰和簡潔。 我正在用Python開發一個工具,使用Flask。它意味着是一個內聯網。這個想法是我有一個客戶端頁面。有它的名字,許多其他信息和一個巨大的清單。燒瓶閃光和url_for與AJAX

該信息已寫入輸入字段,以便用戶只需在那裏編輯它們,按回車鍵,頁面重新加載編輯的信息(使用閃爍的消息和咆哮通知)。 這個龐大的清單迫使我轉向使用AJAX的系統,因爲我希望用戶可以在用戶勾選框並在輸入中輸入內容時進行「實時」更新,而無需重新加載頁面。

因此,我也將我的基本輸入信息切換到AJAX,以避免重新加載法師。

我遇到兩個問題:

第一個涉及信息閃爍瓶的特點。我有一個方法,更新數據庫中的客戶端名稱,閃爍消息(成功或失敗,取決於許多事情),然後再次顯示該頁面。爲了避免頁面重新加載,我使用AJAX管理表單提交。

問題是,我的python方法會刷新消息。一旦我回到我的html頁面(由於它是AJAX,它沒有被重新加載),Jinja2的get_flashed_message函數沒有返回任何內容,因爲它沒有被更新。因此,我不可能找回那些閃過的信息。

我怎樣才能得到這些?我看到的唯一解決方案是擺脫閃存的使用,編寫我自己的消息系統,我會從方法返回,然後在javascript中處理。這看起來非常愚蠢,因爲Flash是Flask的一個功能,並且它被AJAX「無用」了嗎?我覺得我失去了一些東西。

第二個問題涉及url_for(作注,到現在爲止,我的腦子裏閃過信息管理在我的基地佈局,調用,通過所有消息運行並將其顯示爲低吼通知模板製造)。這裏是我的形式,編輯客戶端的名稱:

<form id="changeClientName" method="POST" action="{{ url_for('clients.edit_client_name', name=client.name) }}" style="display:inline !important;"> 
    <input type="text" name="name" class="form-control" value="{{ client.name }}" > 
    <input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/> 
</form> 

正如你所看到的,動作屬性使用url_for調用編輯客戶正確的方法。我的方法如下所示:

@mod.route('/edit/<name>/', methods=['POST']) 
def edit_client_name(name): 

所以url路徑是/ edit/the_client_name。因此,在編輯之後,如果我們要重新編輯此名稱,則新URL爲/ edit/the_new_client_name。 很顯然,一旦方法被調用,我的AJAX就必須改變這個action屬性,用新的URL替換它(如果用戶想重新編輯名稱而不改變頁面/重新加載頁面)。這是我的第二個問題。

新名稱存儲在JavaScript中。行動仍然是舊的網址。所以我必須使用新名稱來調用url_for。我發現絕對沒有辦法將一個Javascript變量傳遞給Jinja2。

我想這一點:

url_for('clients.edit_client_name', name=client.name) 

要成爲這樣的:

url_for('clients.edit_client_name', name=my_javascript_variable_one_way_or_another) 

我只好打電話修飾形式的屬性的js函數,並修改我的動作與屬性這個新的url_for.But我發現沒有辦法讓這個簡單的事情,即給Jinja2一個JavaScript變量,這似乎對我來說不太可能。

所以這裏是我的兩個問題。我怎樣才能使Flash兼容AJAX?我怎樣才能傳遞一個javascript屬性給Jinja2?

我真誠希望爲這兩個「愚蠢」的問題找到解決方案。我能看到的唯一解決方案就是編寫我自己的消息系統,這會打敗flash的目標,使其對AJAX(這看起來很愚蠢)毫無用處,並且在我的模板中對URL進行硬編碼,這完全違背了Flask的最初興趣來自方法的URL獨立性和URL更改非常靈活。

謝謝。

+1

你可以把它分成兩個單獨的問題,你知道嗎?至於第一個,你返回的「Flash消息」作爲你的JSON響應的一部分,並讓客戶端JavaScript處理顯示它與適當的類(即錯誤/成功) – Oerd

+0

是的,我猶豫分開這個,但這兩個問題似乎實際上,因爲兩者都涉及Jinja2如何管理AJAX,因爲它的url_for方法和get_flashed_messages都是如此。我可能做出了錯誤的決定,但不知道:/至於你的想法,這就是我的想法,但在這種情況下,它首先否定閃光的使用!由於我必須手動獲取閃存消息並顯示它們,所以我可以不使用flash(),而是使用基本的字符串列表,最後它是一樣的,不是嗎? – lap0573

+1

我認爲Oerd是對的。通過JS處理Flash消息。至於第二個問題,爲什麼不傳遞一些不會改變的東西,比如他們的id而不是他們的名字? –

回答

3

我會試穿這個,但我不確定我完全理解這個問題:D。下面的代碼沒有經過測試,它更符合僞碼的要求!

您的第一個問題是(如果我正確理解您的意思)您是通過ajax進行部分更新,並希望在部分更新後稍後獲取更新結果。取代後面的更新結果,您應該在每個ajax調用後返回它們。所以,如果你有更新的代碼看起來像這樣:

data = $('#my-form').serialize() 
$.post(update_url, data, function (results) { 
    // Here you check results. 
    if (results.success) { 
     $('#update-div').message('Update Success') 
    } else { 
     $('#update-div').message('Update Failed: ' + results.error_msg) 
    } 
}) 

那麼你更新路由將有類似下面的代碼:

from flask import jsonify 

@app.route('/partialupdate/<int:userid>', methods=['POST']) 
def partial_update(userid): 
    try: 
     # fetch the user, perform the updates and commit 
     return jsonify(success=1) 
    except Exception, e: 
     return jsonify(success=0, error_msg=str(e)) 

你涉及URL生成第二個問題可以通過使用USERID,而不是固定的客戶名稱。 永遠不要使用客戶名稱以外的任何搜索:D。在這種情況下使用用戶ID。用戶標識通常是數據庫中特定用戶的主鍵。如果你不使用數據庫,那麼以某種方式生成你自己的用戶標識並將其附加到用戶 - 它應該是每個用戶的唯一編號。使用用戶ID意味着您可以隨時使用像'/ edituser/1'這樣的網址進行編輯。

+1

謝謝你的回答,確實加入了Eric Workman的一個。至於閃光,我會先嚐試一下,如果太奇怪,我會使用你所示的手工編碼系統。至於第二個,完全是,那就是我要做的!謝謝。 – lap0573

0

通過了解flash_message.html的格式化方式,您可以編寫一個簡單的javascript方法來替換燒瓶「flash」方法的功能。

function flash(message,category){ 
    if (category == 'error'){ 
     var icon='icon-exclamation-sign'; 
     category='danger'; 
     } 
    else if (category == 'success') 
     var icon='icon-ok-sign'; 
    else 
     var icon='icon-info-sign';  
    $('<div class="alert alert-'+category+'"><i class="'+icon+'"></i>&nbsp;<a class="close" data-dismiss="alert">×</a>'+ message +'</div>').prependTo('#maincontent').hide().slideDown(); 
    $.smoothScroll({ 
    scrollElement: $('body'), 
    scrollTarget: '#mainContent' 
    }); 
} 

url_for可能會有點棘手,但可能。

1

我也有這個要求。爲了充實保羅魔杖的答案,這裏是我做到了(注意,生成的標記是自舉3):

把一個空div在模板中的提示信息:

<div id="flash"></div> 

你的Ajax撥打:

$.post("/foo/bar", JSON.stringify({'calls': 'whatever'}), function(returnedData) { 
    $('#flash').append(flashMessage(JSON.parse(returnedData))); 
}); 

,並使用分析功能:

var flashMessage = function(data){ 
    html = ''; 
    for (i=0; i<data.length; i++) { 
    html += '<div class="alert alert-' + data[i]['type'] + '"><a href="#" class="close" data-dismiss="alert">&times;</a>' + data[i].message + '</div>'; 
    } 
    return html; 
}; 

在你的路由處理AJAX請求,只返回一個JSON對象,看起來像:

[{'type': 'success', 'message': 'Here is a message'}]

在「類型」是自舉3狀態類型,即。成功,信息,警告,危險。字典被包裝在一個列表中,所以如果需要的話可以傳遞多個字符。