我开始使用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应用程序的最佳方法。任何建议将不胜感激。