我开始使用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”。

在JQM更改HTML代码之前,有什么方法可以执行JSON调用?

PD:之所以不能动态构建整个HTML页面(包括i18n文本),是因为将来我想用PhoneGap或类似的外壳封装Web应用程序,并且希望在其中分发HTML页面,CSS和脚本应用程序,并最大程度地减少服务器的数据流量。

提前致谢:

卡洛斯

编辑:更改文本后调用$scope.trigger('create')不能解决问题。

最佳答案

最后,我找到了解决问题的解决方案,捕获了“pagebeforecreate”事件。

我在需要国际化的每个页面上调用此函数,并传递需要调用的服务器操作和页面ID:

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);
    });
}

最后,这是产生i18n资源的jsp。我使用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应用程序的最佳方法。任何建议将不胜感激。

10-05 21:04
查看更多