jQuery Tree (pioz): дерево неправильно отображает файлы cookie - PullRequest
0 голосов
/ 04 апреля 2011

Я использую дерево jQuery отсюда https://github.com/pioz/jquery-tree#readme

Проблема заключается в рендеринге дерева, когда я сохраняю cookie. Когда приходит время перерисовать его, код работает неправильно, если я не следую конкретному способу размещения упорядоченных списков.

Полагаю, лучше всего взглянуть на этот демонстрационный код, который я выложил.

http://jsbin.com/emaku4/23

  1. Все дерево открыто
  2. Нажмите на стрелку уровня 3, чтобы развернуть (для обоих деревьев)
  3. сделать обновление

Теперь, первое дерево отображается правильно, файлы cookie показывают, что было открыто ранее, а 2-е дерево нет. Я думаю, это потому, что на втором я положил один без подуровней поверх другого с подуровнями (тот, который называется ЭТО РАЗНИЦА).

Есть ли способ настроить код таким образом, чтобы он мог правильно отображать вид с помощью файлов cookie, независимо от того, какой у меня порядок на любом из подуровней?

// Require jQuery
// Use jQuery.cookie if you want to restore the previous expansion of the tree

jQuery.fn.tree = function(options) {

  // Setup default options
  /** Avaiable options are:
   *  - open_char: defeault character to display on open node in tree
   *  - close_char: defeault character to display on close node in tree
   *  - default_expanded_paths_string: if no cookie found the tree will be expand with this paths string
  **/
  if(options === undefined || options === null)
    options = {};
  var open_char = options.open_char;
  var close_char = options.close_char;
  var default_expanded_paths_string = options.default_expanded_paths_string;
  if(open_char === undefined || open_char === null)
    open_char = '▼';
  if(close_char === undefined || close_char === null)
    close_char = '►';
  if(default_expanded_paths_string === undefined || default_expanded_paths_string === null)
    default_expanded_paths_string = '0';

  // Get the expanded paths from the current state of tree
  jQuery.fn.save_paths = function() {
    var paths = [];
    var path = [];
    var open_nodes = jQuery(this).find('li span.open');
    var last_depth = null;
    for(var i = 0; i < open_nodes.length; i++) {
      var depth = jQuery(open_nodes[i]).parents('ul').length-1;
      if((last_depth == null && depth > 0) || (depth > last_depth && depth-last_depth > 1))
        continue;
      var pos = jQuery(open_nodes[i]).parent().prevAll().length;
      if(last_depth == null) {
        path = [pos];
      } else if(depth < last_depth) {
        paths.push(path.join('/'));
        var diff = last_depth - depth;
        path.splice(path.length-diff-1, diff+1);
        path.push(pos);
      } else if(depth == last_depth) {
        paths.push(path.join('/'));
        path.splice(path.length-1, 1);
        path.push(pos);
      } else if(depth > last_depth) {
        path.push(pos);
      }
      last_depth = depth;
    }
    paths.push(path.join('/'));
    try { jQuery.cookie(this.attr('class'), paths.join(',')); }
    catch(e) {}
  };

  // This function expand the tree with 'path'
  jQuery.fn.restore_paths = function() {
    var paths_string = null;
    try { paths_string = jQuery.cookie(this.attr('class')); }
    catch(e) { paths_string = default_expanded_paths_string; }
    if(paths_string === null || paths_string === undefined)
      paths_string = default_expanded_paths_string;
    var paths = paths_string.split(',');
    for(var i = 0; i < paths.length; i++) {
      var obj = jQuery(this);
      var path = paths[i].split('/');
      for(var j = 0; j < path.length; j++) {
        obj = jQuery(obj.children('li').children('ul')[path[j]]);
        obj.show();
        obj.parent().children('span').attr('class', 'open');
        obj.parent().children('span').html(open_char);
      }
    }
  };

  for(var i = 0; i < this.length; i++) {
    if(this[i].tagName === 'UL') {
      // Make a tree
      jQuery(this[i]).find('li').has('ul').prepend('<span class="close" style="cursor:pointer;">' + close_char + '</span>');
      jQuery(this[i]).find('ul').hide();
      // Restore cookie expand path
      jQuery(this[i]).restore_paths();
      // Click event
      jQuery(this[i]).find('span').live('click', {tree : this[i]}, function(e) {
        if (jQuery(this).attr('class') == 'open') {
          jQuery(this).parent().children('ul').hide('slow');
          jQuery(this).attr('class', 'close');
          jQuery(this).html(close_char);
        } else if (jQuery(this).attr('class') == 'close') {
          jQuery(this).parent().children('ul').show('slow');
          jQuery(this).attr('class', 'open');
          jQuery(this).html(open_char);
        }
        jQuery(e.data.tree).save_paths();
      });
    }
  }
}

Ответы [ 2 ]

2 голосов
/ 06 мая 2011

Проблема в строке 34 файла jquery.tree.js (в пределах jQuery.fn.save_paths()):

var pos = jQuery(open_nodes[i]).parent().prevAll().length;

open_nodes[i] - это открытие / закрытие span, егоparent - li, и поэтому с prevAll() он считает количество предыдущих li s.

Но далее вниз по в строке 68 (в пределах jQuery.fn.restore_paths()):

obj = jQuery(obj.children('li').children('ul')[path[j]]);

он использует сохраненную позицию из save_paths(), чтобы найти nth ul.

Так что в вашем случае, после расширения первого (и только) ul, save_paths() помнит 1 (так как перед ul стоит 1 li), но при перезагрузке страницы restore_paths() попытался развернуть "второй" ul (первый - 0, aсекунда ul - это 1).

Хм, я не думаю, что объясняю это очень хорошо ...


В любом случае, решение состоит в том, чтобы изменить строку34 от этого:

var pos = jQuery(open_nodes[i]).parent().prevAll().length;

до этого:

var pos = jQuery(open_nodes[i]).parent().prevAll(':has(">ul")').length;

Это обеспечит пропуск li с, которые не имеют вложенного ul при расчете тока ul.


Я отправил запрос на извлечение в pioz сэто исправить.В то же время вы можете использовать исправленную версию с моего форка: https://github.com/jefferyto/jquery-tree/raw/counting-fix/jquery.tree.js.

Вы можете увидеть, как она работает здесь: http://jsbin.com/emaku4/28

Обновление: pioz commit(другое) исправление.Вы можете скачать рабочий код на https://github.com/pioz/jquery-tree. Спасибо, пиоз!

1 голос
/ 03 июля 2012

Посмотрите на это: http://docs.jquery.com/Plugins/Treeview/treeview

Установить опцию сохранения для куки, как это:

$(".selector").treeview({
    persist: "cookie"
});

Это более простой способ отображения дерева.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...