JQuery Mobile: обработка JSON до мобильных улучшений - PullRequest
3 голосов
/ 15 ноября 2011

Я начинаю разрабатывать мобильное приложение с помощью jQuery Mobile. Идея состоит в том, чтобы создать HTML-статические страницы, и перед их отображением вызовите сервер, чтобы получить текст i18n для меток и кнопок ввода. Я отмечаю элементы HTML, которые могут изменить внутренний текст, специальным атрибутом: «data-i18n»:

Для этикетки:

<label data-i18n="login.username" for="loginPaciente.username">login.username</label>

Для кнопки:

<button data-i18n="login.submit" type="submit" data-theme="a">login.submit</button>

Я звоню на сервер, используя JSON:

$('#pageLogin').live('pagebeforeshow',function(event, ui){
          var action = "/MyServerApp/namespace1/mobile_Action_Login_configPage.action";
          $.getJSON(action, function(data) {
              var resources =  data.i18n_resources;
              var id, text;
              var $scope = $('#pageLogin');
              for (i=0; i<resources.length; i++){
                  id = resources[i].id;
                  text = resources[i].text;
                  $scope.find('[data-i18n="' + id + '"]').html(text);
              } 
          });
    });

Это отлично работает с метками, потому что JQM не изменяет эти элементы HTML. Проблема возникает с кнопкой, потому что JQM скрывает определенную мной кнопку и создает новый диапазон для визуализации кнопки. Когда я читаю результат JSON, я могу найти и изменить определенную мной кнопку, но не новый диапазон, созданный JQM, поэтому текст, отображаемый на экране, является старым: "login.submit".

Есть ли способ выполнить вызов JSON, прежде чем JQM изменит код HTML?

PD: причина не динамического построения всей HTML-страницы (включая тексты i18n) заключается в том, что в будущем я хочу инкапсулировать веб-приложение с PhoneGap или аналогичной оболочкой и хочу распространять HTML-страницы, CSS и скрипты внутри приложения, и минимизировать трафик данных с сервером.

Заранее спасибо:

Карлос.

EDIT: вызов $scope.trigger('create') после изменения текста не решает проблему.

Ответы [ 2 ]

1 голос
/ 16 ноября 2011

Наконец-то я нашел решение своих проблем сам, поймав событие "pagebeforecreate".

Я вызываю эту функцию на каждой странице, которую мне нужно интернационализировать, передавая действие сервера, которое мне нужно вызвать, и идентификатор страницы:

function utils_loadConfigPage(action, pageid){
  $(document).bind("pagebeforecreate", function(){
    var $page = $('#' + pageid);
    var _action = action; 
    var paramCallback = "jsoncallback=?";
    var concat = "?";
    if (_action.indexOf("?")!=-1){
        concat = "&";
    }
    _action += concat + paramCallback;
    $.ajaxSetup({"async": false});
    $.getJSON(_action, function(data){
        utilis_doConfigPage(data, $page);
    });
    $.ajaxSetup({"async": true});
  });
}

Обратите внимание, что я заставляю использовать синхронные звонки на сервер, чтобы избежать улучшения мобильных страниц до того, как тексты i18n были готовы. Эта функция вызывается в обратном вызове json:

function utils_doConfigPage(data, $scope){
    utils_seti18nTexts(data, $scope);
    utils_setPlaceholders($scope);
}

Эта функция находит все элементы i18n и заменяет их внутренний html переведенными текстами:

function utils_seti18nTexts(data, $scope){

  var resources =  data.i18n_resources;
  var id, text;
  for (i=0; i<resources.length; i++){
    id = resources[i].id;
    text = resources[i].text;
    $scope.find('[data-i18n="' + id + '"]').html(text);
  }
}

Эта функция переопределяет заполнители для входных данных:

function utils_setPlaceholders($scope){

    $scope.find('div[data-role="fieldcontain"].ui-hide-label').each(function(){
        var textLabel = $(this).find('label').html();
        $(this).find('.placeholder').attr('placeholder', textLabel);
    }); 
}

И, наконец, это jsp, который создает ресурсы i18n. Я использую Struts2, поэтому JSP не вызывается напрямую. Я вызываю действие, а JSP - это только представление. Ресурсы i18n получены с использованием возможностей Struts2:

<%@ page contentType="application/json; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<s:property value="jsoncallback" />({
"i18n_resources":
    [
        {
            "id" : "MOBILE_APP_NAME",
            "text" : "<s:text name="APP_NAME" />"
        }
        ,{
            "id" : "TITLE_LOGIN",
            "text" : "<s:text name="TITLE_LOGIN" />"
        }
        ,{
            "id" : "LOGIN_USERNAME",
            "text" : "<s:text name="LOGIN_USERNAME" />"
        }
        ,{
            "id" : "LOGIN_PASSWORD",
            "text" : "<s:text name="LOGIN_PASSWORD" />"
        }
        ,{
            "id" : "BUTTON_OK",
            "text" : "<s:text name="BUTTON_OK" />"
        }
        ,{
            "id" : "MOBILE_APP_FOOTER",
            "text" : "<s:text name="MOBILE_APP_FOOTER" />"
        }
    ]
})

Я не знаю, является ли это лучшим способом интернационализации приложения JQM. Любое предложение будет оценено.

0 голосов
/ 15 ноября 2011

Вы можете просто изменить текст элемента <span> с помощью класса ui-btn-text:

$scope.find('[data-i18n="' + id + '"]').find('.ui-btn-text').html(text);

Или, если вы не уверены, что элемент был инициализирован jQuery Mobile, вы можете проверить наличие ui-btn-class first:

var $btn_text = $scope.find('[data-i18n="' + id + '"]').find('.ui-btn-text');
if ($btn_text.length > 0) {
    $btn_text.html(text);
} else {
    $scope.find('[data-i18n="' + id + '"]').html(text);
}
...