Динамическое заполнение списка (три списка, по одному на страницу - все в одном HTML) - PullRequest
0 голосов
/ 18 января 2012

У меня есть одна HTML-страница, на которой мне нужно три jqm pages (data-role = page) (с именем #one, #two, #three). На каждой странице кроме #one у меня также есть кнопка «назад» в заголовке. На каждой странице у меня есть простой listview. При генерации HTML заполняется только listview на странице #one. При нажатии на элемент в списке я выполняю некоторый ajax, чтобы получить содержимое следующего списка и заполнить его. Все отлично работает, пока я не нажму кнопку назад и не выберу другой элемент из списка. В результате красиво отформатированный jqm listview становится вертикальным списком ссылок, а не стилями jqm и цветными горизонтальными полосами с содержимым.

Мой HTML и скрипт приведены ниже.

<div data-role="page" id="one">
    <div data-role="header">
        <h1>Make</h1>
    </div>
    <div data-role="content">
        <ul data-role="listview" data-theme="b" id="cutpoint_makes_mobile">
            @foreach (var make in Model)
            {
                <li><a href="#">@make</a></li>
            }
        </ul>
    </div>
</div>
<div data-role="page" id="two">
    <div data-role="header">
        <a href="#one" data-role="button" data-icon="arrow-l">Back</a>
        <h1>Model</h1>
    </div>
    <div data-role="content">
        <ul data-role="listview" data-theme="b" id="cutpoint_models_mobile">
        </ul>
    </div>
</div>
<div data-role="page" id="three">
    <div data-role="header">
        <a href="#two" data-role="button" data-icon="arrow-l">Back</a>
        <h1>Size</h1>
    </div>
    <div data-role="content">
        <ul data-role="listview" data-theme="b" id="cutpoint_sizes_mobile">
        </ul>
    </div>
</div>
<div data-role="page" id="four">
    <div data-role="header">
        <a href="#three" data-role="button" data-icon="arrow-l">Back</a>
        <h1>Details</h1>
    </div>
    <div data-role="content">
        <h2 id="cutpoint_detail_mobile">
        </h2>
    </div>
</div>

... и код jquery ...

var make = null;
var model = null;

$(document).ready(function () {
    $("#cutpoint_makes_mobile a").click(function () {
        make = $(this).text();
        loadAllModelsMobile_Request(make);
    });
    $("#cutpoint_models_mobile a").live("click", function () {
        model = $(this).text();
        loadAllSizesMobile_Request(make, model);
    });
    $("#cutpoint_sizes_mobile a").live("click", function () {
        var size = $(this).text();
        loadDetailsMobile_Request(make, model, size);
    });
});

// NOTE, only the load models ajax calls are listed for brevity
// *** loadAllModelsMobile (Request/Response/Error) ***
function loadAllModelsMobile_Request(make) {
    var qs = "make=" + make;
    var url = "/HomeJson/CutPointsAllModels";
    $.ajax({
        type: "POST",
        url: url,
        dataType: "json",
        data: qs,
        success: loadAllModelsMobile_Response,
        error: loadAllModelsMobile_Error
    });
}
function loadAllModelsMobile_Response(data) {
    if (data.Success) {
        $("#cutpoint_models_mobile").find("li").remove().end();
        model = null;
        $.each(data.Data, function () {
            $("#cutpoint_models_mobile").append('<li><a href="#">' + this + '</a></li>');
        });
        $.mobile.changePage($("#two"));
    } else {
        // ToDo: handle errors
        //$("#admin_alert_msg").text(data.Data);
        //$("#dlg_admin_alert").dialog("open");
    }
}
function loadAllModelsMobile_Error(xhr) {
    // ToDo: handle errors
    //showAjaxErrorMessage("loadAllModelsMobile_Error", xhr.status, xhr.response);
}

Я даже использовал уведомление о событии pagebeforechange и очистил там li, но без изменений (то же самое, что очистить li в ответе ajax, поскольку это было до смены страницы).

Мой вопрос : как мне заставить jqm стилизовать список после того, как он был один раз стилизован, и я удаляю / заменяю его содержимое?

1 Ответ

3 голосов
/ 18 января 2012

Некоторые заметки; эта строка не нуждается в вызове функции .end(), который используется для возврата к предыдущему выбору, и вы ничего не делаете с выбором:

$("#cutpoint_models_mobile").find("li").remove().end();

Должен измениться на:

$("#cutpoint_models_mobile").find("li").remove();

Добавление каждого LI требует больших затрат ресурсов ЦП, лучшей альтернативой является либо создание строки, либо создание массива LI.

Изменение:

    $.each(data.Data, function () {
        $("#cutpoint_models_mobile").append('<li><a href="#">' + this + '</a></li>');
    });

Кому:

    var output = [];
    for (var i = 0, len = data.Data.length; i < len; i++) {
        output[output.length] = '<li><a href="#">' + data.Data[i] + '</a></li>';
    }
    $("#cutpoint_models_mobile").append(output.join(''));

Используемый мной цикл for также работает быстрее, чем $.each() (хотя $.each() немного быстрее, чем $(<selector>)).each() и for (a in b)).

Теперь перейдем к вашему вопросу.

Вы должны вручную обновить listview виджеты (и все остальные виджеты), если вы обновите их структуру. Вы можете сделать это с помощью функции .listview(), передав ей строку «refresh». Так что пример чуть выше этого получился бы так:

    var output = [];
    for (var i = 0, len = data.Data.length; i < len; i++) {
        output[output.length] = '<li><a href="#">' + data.Data[i] + '</a></li>';
    }
    $("#cutpoint_models_mobile").append(output.join('')).listview('refresh');

Документация для listview виджетов находится здесь: http://jquerymobile.com/demos/1.0/docs/lists/docs-lists.html (раздел об обновлении listview находится внизу страницы)

UPDATE

Иногда вы сталкиваетесь с проблемой незнания, была ли инициализирована listview или нет. Вы можете проверить наличие класса .ui-listview в элементе <ul>, если он существует, то listview уже инициализирован:

    var output    = [],
        $listview = $("#cutpoint_models_mobile");
    for (var i = 0, len = data.Data.length; i < len; i++) {
        output[output.length] = '<li><a href="#">' + data.Data[i] + '</a></li>';
    }

    $listview.append(output.join(''))
    if ($listview.hasClass('ui-listview')) {
        $listview.listview('refresh');
    } else {
        $listview.trigger('create');
    }
...