我已经花了好几个小时,我还没有取得很大进展,所以我希望其中一位出色的SO大家可以帮助我。这是问题......
我正在通过jQuery的jQuery插件实现一个树。我正在从我们的webapp以编程方式将数据填充到树中,通过json转储到asp:HiddenField中,基本上就像这样:
JavaScriptSerializer serializer = new JavaScriptSerializer();
string json = serializer.Serialize(Items);
json = json.ToLower();
data.Value = json;
然后,树从隐藏字段中拉出json以构建自身。这完全正常,直到我尝试保留选择/打开节点的数据。为了简化我的问题,我将一些json数据硬编码到树中,并尝试使用cookie插件来保存树状态数据。这无论出于何种原因都不起作用。我已经看到其他问题,人们需要按特定顺序加载插件等,这并没有解决我的问题。我尝试使用html_data进行相同的设置,它完美无缺。通过这种工作持久性,我将cookie插件转换为将数据保存在不同的asp:hiddenfield中(我们的应用程序中不能使用cookie作为此类事物。)
本质上cookie操作是相同的,它只是将节点数组保存为隐藏字段的值。这适用于html_data,仍然没有json,我还没有能够把手指放在它失败的地方。
这是jQuery.cookie.js的替代品:
jQuery.persist = function(name, value) {
if (typeof value != 'undefined') { // name and value given, set persist
if (value === null) {
value = '';
}
jQuery('#' + name).attr('value', value);
} else { // only name given, get value
var persistValue = null;
persistValue = jQuery('#' + name).attr('value');
return persistValue;
}
};
除了一些变量名称更改外,jstree.cookie.js代码完全相同。 这是我的树:
$(function() {
$("#demo1").jstree({
"json_data": {
"data" : [
{
"data" : "A node",
"children" : [ "Child 1", "Child 2" ]
},
{
"attr": { "id": "li.node.id" },
"data" : {
"title": "li.node.id",
"attr": { "href": "#" }
},
"children": ["Child 1", "Child 2"]
}
]
},
"persistence": {
"save_opened": "<%= open.ClientID %>",
"save_selected": "<%= select.ClientID %>",
"auto_save": true
},
"plugins": ["themes", "ui", "persistence", "json_data"]
});
});
数据 - 被正确存储在隐藏字段中,问题发生在回发上,它不会重新打开节点。任何帮助将不胜感激。
在仔细研究了这个之后,我只想解释一下,在我看来,问题是在尝试执行持久性操作时,尚未从JSON_data构建树。有没有办法推迟这些操作,直到树完全加载?
答案 0 :(得分:2)
如果有人仍在尝试在jsTree 3.0+版本上执行相同类型的操作,则可以更轻松地完成相同类型的功能,而无需编辑任何jsTree的核心JavaScript,也无需依赖在&#34;州&#34;插件(版本1.0 - &#34;持久性&#34;):
var jsTreeControl = $("#jsTreeControl");
//Can be a "asp:HiddenField"
var stateJSONControl = $("#stateJSONControl");
var url = "exampleURL";
jsTreeControl.jstree({
'core': {
"data": function (node, cb) {
var thisVar = this;
//On the initial load, if the "state" already exists in the hidden value
//then simply use that rather than make a AJAX call
if (stateJSONControl.val() !== "" && node.id === "#") {
cb.call(thisVar, { d: JSON.parse(stateJSONControl.val()) });
}
else {
$.ajax({
type: "POST",
url: url,
async: true,
success: function (json) {
cb.call(thisVar, json);
},
contentType: "application/json; charset=utf-8",
dataType: "json"
}).responseText;
}
}
}
});
//If the user changes the jsTree, save the full JSON of the jsTree into the hidden value,
//this will then be restored on postback by the "data" function in the jsTree decleration
jsTreeControl.on("changed.jstree", function (e, data) {
if (typeof (data.node) != 'undefined') {
stateJSONControl.val(JSON.stringify(jsTreeControl.jstree(true).get_json()));
}
});
此代码将创建一个jsTree并保存它&#34; state&#34;进入隐藏值,然后在重新创建jsTree时回发,它将使用其旧的&#34;状态&#34;从&#34; HiddenField&#34;恢复而不是进行新的AJAX调用并丢失用户所做的扩展/选择。
答案 1 :(得分:1)
使用JSON数据正常工作。我不得不在jstree里面编辑“重新打开”和“重新选择”功能。
以下是需要它的任何人的新功能重新打开功能。
reopen: function(is_callback) {
var _this = this,
done = true,
current = [],
remaining = [];
if (!is_callback) { this.data.core.reopen = false; this.data.core.refreshing = true; }
if (this.data.core.to_open.length) {
$.each(this.data.core.to_open, function(i, val) {
val = val.replace(/^#/, "")
if (val == "#") { return true; }
if ($(("li[id=" + val + "]")).length && $(("li[id=" + val + "]")).is(".jstree-closed")) { current.push($(("li[id=" + val + "]"))); }
else { remaining.push(val); }
});
if (current.length) {
this.data.core.to_open = remaining;
$.each(current, function(i, val) {
_this.open_node(val, function() { _this.reopen(true); }, true);
});
done = false;
}
}
if (done) {
// TODO: find a more elegant approach to syncronizing returning requests
if (this.data.core.reopen) { clearTimeout(this.data.core.reopen); }
this.data.core.reopen = setTimeout(function() { _this.__callback({}, _this); }, 50);
this.data.core.refreshing = false;
}
},
问题是它试图通过自定义属性找到
if ($(("li[id=" + val + "]")).length && $(("li[id=" + val + "]")).is(".jstree-closed")) { current.push($(("li[id=" + val + "]"))); }
而不是
if ($(val).length && $(val).is(".jstree-closed")) { current.push(val); }
就这么做了。使用类似的过程,我也能够以这种方式保留选定的节点。
希望这对某人有所帮助。