Мозговой штурм !!!! Построение иерархической модели данных.
Всем доброго времени суток.
Есть элементы с классом column в них вложены элементы с классом portlet, в portlet вложены элементы с классом column, а в этот новый column снова portlets и так как угодно много. стоит задача превратить всю эту абракадабру в дерево данных и хранит в обьекте. Должно получится что то вроде ........................колумн ......................./ ............портлет- колумн ........../............\ колумн ..............колумн ..........\ ...........портлет сразу отвечаю на вопрос а нафига это надо. Всё дело в том что мне надо анализировать вложенность портлетов и колумнов при каждом движении мышки над областью портлетов, поэтому я стремлюсь прокешировать информацию чтобы сократить до минимума работу с селекторами, и добиться приличной скорости, за счёт работы только с нужными ветвями дерева. в результате всего должен получится аналог UI sortable Но с возможностью размещать ёмкости для портлетов(.column) внутри портлетов, к сожалению ui sortable глубокую вложенность не поддерживает. Пытаюсь реализовать создание дерева методом рекурсии. function trackman (obj,type){ //рекурсивная функция обходчик. this.link=obj; //ссылка на элемент DOM для каких нибудь манипуляций с ним this.name=$(obj).attr("id"); // ID портлета или column this.subject=[]; // обьявляем массив в котором храним дочерние обьекты. self=this; // делаем ссылку на контекст чтобы использовать его внутри each if (type==1){ // если изучаем column, тоесть ищем портлеты jQuery.each($(obj).find(">.portlet"), function(){ self.subject.push(new trackman(this,-1)); //вызываем обходчик для каждого найденного портлета }); } else { //если изучаем portlet, тоесть ищем column jQuery.each($(obj).find(".column:not(.column .column)"), function(){ self.subject.push(new trackman(this,1)); //вызываем обходчик для каждого найденного column }); } //функция строительства дерева function arrangerRefrash(){ var i=0; jQuery.each($(".wrpage> .column"),function(){ // перебираем все column arrObj[i]=new trackman (this,1) i=i+1; }); } но нофига невыходит, так как вместо массива с портлет я получаю portlets вложенные друг в друга. |
только сейчас пришла идея, заменить $.each на обычный for, это позволит упростить код и избавится от захвата контекста в self. Но не уверен что это как то поможет ))))))
|
А вложенные друг в друга portlet и column Вас, судя по коду, не интересуют, верно я понял?
Оффтоп: не понял Вашу подпись :) Ни первую её мысль, ни вторую... :blink: |
Portlet может находится только внутри column
Column'ы только внутри portlet. Portlet не может находится внутри portlet непосредственно. Портлет можно разместить только в контейнере column. А вот уже column находится в каком нибудь портлете. Пример мы имеем column во всю страницу. 1)Пользователь пераскивает в него портлет "текст". и пишет большими буквами заголовок. 2) Затем он перетаскивает ниже текста портлет "Layer", внутри которого есть 3 column- левый,центральный,и правый. как при стандартной разметки страницы 3) пользователь заполняет column'ы портлетами с контентом. Вот собственно откуда вложенность. офтоп: как то нехочется обьяснять свой статус буквально )). Спросите у майкрософта ))). |
А, ну тогда всё логично)
|
Цитата:
или это логично но не работает )))) |
А вот это вот похоже работает.
function trackman (obj,type){ this.link=obj; //ссылка на обьект для манипуляция. this.name=$(obj).attr("id"); //сохраняем id this.subject=[]; //здесь храним вложенные обьекты if (type==1){ // если изучаем column, тоесть ищем портлеты finder=$(obj).find(">.portlet"); //делаем выборку length=finder.length; // определяем длинну выборки for (i=0;i<length;i++){ // перебираем выборку в цикле this.subject.push(new trackman(finder[i],-1)); // передаём в рекурсию } console.log(this); //показываем в логе что у нас получилось } else { //если изучаем portlet, тоесть ищем column jQuery.each($(obj).find(".column:not(.column .column)"), function(){ // здесь пока на FOR не менял, но поменяю self.subject.push(new trackman(this,1)); });//*/ } } function arrangerRefrash(){ var i=0; jQuery.each($(".wrpage> .column"),function(){ // перебираем все column arrObj[i]=new trackman (this,1) ; i=i+1; }); } Значит проблема была в контексте сохранённом в self, хотя механизьм это проблемы я так до конца и не понял. Всё равно спасибо, недогнал пока не написал на форум. ))) |
Цитата:
Цитата:
|
Цитата:
column Код Код-ссылка на экземпляр в portlet Другие поля portlet Код Код-ссылка на экземпляр в column Другие поля |
ksa дело говорит, храни все не в иерархическом, а в релиационном виде, алгоритмы будут проще, а скорость в разы выше.
|
Цитата:
если делать дерево при помощи циклов, мне всё равно придётся прибегать к стекам и имулировать рекурсию. Так что реаляционная модель этом плане интереснее так как сводится к двум таблицам. Надо полагать что нужно составить два массива, один с колумнами с указанием родительских portlet. другой с портлетами с указанием родительских column. Как вы предлагаете реализовать решение ? вот код на данный момент, но его результат бесконечная рекурсия. function trackman (obj,type){ this.link=obj; //ссылка на обьект для дальнейших мманипуляций this.name=$(obj).attr("id"); //id анализируемого обьекта this.subject=[]; //вложенные субьекты if (type==1){ // если изучаем column, тоесть ищем портлеты var finder=$(obj).find(">.portlet"); //ссылка на выборку портлетов var length=finder.length; //Количество вложенных портлетов for (i=0;i<length;i++){ // перебор портлетов var thisobj= finder[i]; this.subject.push(new trackman(thisobj,-1)); //вызываем рекурсию } console.log(this); } else { //если изучаем portlet, тоесть ищем column var finder2=$(obj).find(".column:not(.column .column)"); var length2=finder2.length; for(var i2=0;i2<length2;i2++){ thisobj2= finder2[i]; this.subject.push(new trackman(thisobj2,1)); }; } } function arrangerRefrash(){ var i=0; jQuery.each($(".wrpage> .column"),function(){ // перебираем все column //arrObj.push( new trackman (this,1)); arrObj[i]=new trackman (this,1) i=i+1; }); |
Я бы вообще использовал один релиационный набор, так как это проще, тем более дерево здесь по сути одно.
|
В общем то я так и поступил :)
Алгоритм в разы проще, и что удивительно скорости хватает во всех браузерах, даже если не кешировать заранее. Тем не менее от кеширования я конечно не отказался. Ограничился одним реляционным набором, но не потому что так проще, а потому что порядок следования обьектов в этом наборе соответствует вложенности. ТОБИШ вибираю таким макаром jQuery.each($(".column, .portlet"),function(){ // перебираем все column arrObj.push (new trackman (this)); }); |
Часовой пояс GMT +3, время: 00:59. |