在我的Django项目中,有一个名为Workspace的MPTT模型(“Dossier”,法语)。与计算机中的目录一样,工作空间可以嵌套在一起。
然后
工作区显示给用户,如上一个屏幕截图所示,就像一棵树。
默认情况下,所有工作区都会展开。当用户单击“ - ”符号时,子工作空间消失,相反,单击“+”时。这是由javascript处理的。
这很有效。但是,我希望在用户刷新页面时保存树状态,这样他就不需要再次展开/折叠所有内容。
我知道我可以通过ajax执行此操作:单击“ - ”或“+”将向服务器发送请求,将工作空间的pk和用户存储在具有状态的数据库中。这对我来说似乎非常复杂,并且它不适用于匿名用户。
更好的想法是用cookie处理这个问题,但我显然在编写javascript代码时犯了一些愚蠢的错误。这是我到目前为止:
$( document ).ready(function() {
// from http://ppk.developpez.com/tutoriels/javascript/gestion-cookies-javascript/
// these are sample functions to write/read cookies took from a tutorial
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
createCookie(name,"",-1);
}
function arrayToCookie(array){ // convert an array to cookie format (coma separated list)
return array.join(',');
}
function cookieToArray(cookie){
return cookie.split(','); // convert a coma-separated cookie to an array
}
var expanded_workspaces_cookie_name = "expandedWorkspaces";
// create the cookie if it does not exists
// The cookie is basically a list of workspaces id that are expanded, written like this : "1,3,12,157"
function initExpandedCookie(){
console.log("init cookie");
console.log('read',document.cookie, readCookie(expanded_workspaces_cookie_name));
console.log(typeof($.cookie(expanded_workspaces_cookie_name)));
if (!readCookie(expanded_workspaces_cookie_name)) {
console.log("new cookie");
createCookie(expanded_workspaces_cookie_name,'', 365);
}
else {
console.log("cookie already exists");
}
}
initExpandedCookie();
function setExpandedWorkspaceToCookie(id, add){
console.log("id =", id, typeof(id), id.length);
var w = readCookie(expanded_workspaces_cookie_name);
console.log('Value of old cookie',document.cookie);
var s = cookieToArray(w);
console.log("Id array before", s);
if (add === true) { // Add the id to the list of expanded workspaces, in cookie
console.log('Add workspace to expanded list');
s.push(id);
console.log("Id array after add", s);
}
else { // remove the id from the list of expanded workspaces, in cookie
console.log('Remove workspace from expanded list');
s.splice(s.indexOf(id));
}
console.log("Id array after", s);
eraseCookie(expanded_workspaces_cookie_name); // empty existing cookie
console.log('Values to insert into cookie', arrayToCookie(s));
createCookie(expanded_workspaces_cookie_name, arrayToCookie(s), 365); // add id lists to cookie
console.log('Value of new cookie',document.cookie );
}
function collapse(e, update_cookie) {
e.addClass("collapsed");
e.removeClass("expanded");
e.find('ul.children').hide();
if (update_cookie==true){
setExpandedWorkspaceToCookie($(e).attr('id'), false);
}
}
function expand(e, update_cookie) {
e.addClass("expanded");
e.removeClass("collapsed");
e.find('ul.children').show();
if (update_cookie==true){
setExpandedWorkspaceToCookie($(e).attr('id'), true);
}
}
$('#workspaces.widget .parent.expanded').each( function(index){
expand($(this)); // Set up already expanded workspaces, so don't update cookie
});
$('#workspaces.widget .parent.collapsed').each( function(index){
collapse($(this)); // Set up already collapsed workspaces, so don't update cookie
});
$('#workspaces.widget .parent .collapse').click(function() {
collapse($(this).closest('.parent'), true); // Trigger when clicking on "-", so update cookie
});
$('#workspaces.widget .parent .expand').click(function() {
expand($(this).closest('.parent'), true); // Trigger when clicking on "-", so update cookie
});
});
当我在浏览器中测试它(在某些工作区上折叠/展开)时,javascript控制台输出:
init cookie
read expandedWorkspaces=; csrftoken=bnR6E6s2CtjCTYEyl5reGTijR3mFXdLF
string
new cookie
id = 220 string 3
Value of old cookie csrftoken=bnR6E6s2CtjCTYEyl5reGTijR3mFXdLF; expandedWorkspaces=
Id array before [""]
Remove workspace from expanded list
Id array after []
Values to insert into cookie
Value of new cookie csrftoken=bnR6E6s2CtjCTYEyl5reGTijR3mFXdLF; expandedWorkspaces=
id = 220 string 3
Value of old cookie csrftoken=bnR6E6s2CtjCTYEyl5reGTijR3mFXdLF; expandedWorkspaces=
Id array before [""]
Add workspace to expanded list
Id array after add ["", "220"]
Id array after ["", "220"]
Values to insert into cookie ,220
Value of new cookie csrftoken=bnR6E6s2CtjCTYEyl5reGTijR3mFXdLF; expandedWorkspaces=,220
我尝试将扩展工作区列表作为逗号分隔列表存储在cookie中。出于某种原因,它在列表中插入一个空字符串。此外,在扩展工作空间时,不是在cookie的末尾添加ID,而只是用它的ID替换整个cookie。
您可以在此处测试它(在Javascript控制台处于打开状态):http://kii.eliotberriot.com/test/items
此外,还有一种更有效的方法来处理我正在做的事情吗?
感谢您的帮助,请告诉我您是否需要更多信息!
答案 0 :(得分:3)
更好的方法是使用Django Sessions,而不是在javascript中处理Cookie。
会话可以由数据库或Cookies支持,您可以在会话中存储任意对象。
每次展开/折叠工作区时,向视图发出ajax请求,以逗号分隔的格式显示扩展工作区的ID。
def handle_ws_expand(request):
request.session['EXPANDED_WORKSPACES'] = request.REQUEST.get("EXPANDED_WS_IDS", "").split(",")
return HttpResponse('Success')
然后,在主页面视图中,输入if条件以检查是否需要扩展工作区。
def my_main_view(request):
# Code to get Workspaces
for ws in workspaces:
if ws.pk in request.session['EXPANDED_WORKSPACES']:
ws.isExpanded = True
OR,直接在模板中处理:
{% for ws in workspaces %}
{% if ws.pk in request.session.EXPANDED_WORKSPACES %}
# Code to expand Workspace
{% endif %}
{% endfor %}
使用会话的最佳部分是,在多个登录用户的情况下,将分别为每个用户维护工作空间的状态。这也适用于已注销的用户。