In a previous post covering the use of Angular.JS on an ASP.NET (or better, DotNetNuke) web app, a was wondering how to solve the problem of localize the js content.
In fact I discovered pretty soon that many strings of the presentation layer were specified inside the js file, defining the angular app, controller, directive,....
So my first thought was to create a specific handler in order to generate the javascript at runtime so that I would have the capability to use the native localization management of ASP.NET or DotNetNuke.
IMHO the handler would have as many cons than pro, or even worst; for example, every js file would have been addressed by the unique handler, breaking the easy file organization of each DNN module or ascx control, ...: much work for a small problem.
So I passed to another approach:
why not concentrate all the strings to localize in a js object inside the ascx file?
the Angular.JS app (controller/directive,...) would be kept in a separate pure js file, with the capability to access the variable once on the client's browser.
The solution is composed by:
1) a method to run on load, in a base class of the module (or User control), with a couple of properties override-able in the specialized module class.
protected void LoadResourcesToJavascript()
{
if (this.ResourceKeysToJavascript.Count() > 0)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("var " + this.ResourceJSVariableName + " = {};\n");
foreach (String s in this.ResourceKeysToJavascript)
{
sb.Append(this.ResourceJSVariableName + "." + s + "= '" + Localization.GetString(s + ".Text", LocalResourceFile) + "';\n");
}
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), this.ResourceJSVariableName + "Resources", sb.ToString(), true);
}
}
protected virtual List ResourceKeysToJavascript
{
get
{
return new List();
}
}
protected virtual String ResourceJSVariableName
{
get
{
return this.ID;
}
}
Note: I use the DNN method to get the localized string. Change it in case of standard ASP.NET project.
Note: The javascript variable name is the control's ID, but it can be specialized in the inherited module class.
2) in the inherited module / user control specialize the ResourceKeyToJavascript list with the resource string required in the javascript.
protected override List ResourceKeysToJavascript
{
get
{
return new List() {
"ConfirmRemoving",
"SailingName",
"Types",
"UnableToFindFriend",
"Saved",
"Error"};
}
}
3) in javascrpit file use the variable name (ASP.NET control's ID) to access the single resource strings:
var str = CrewMemberCollectionV2View.ConfirmRemoving;
if (confirm(str.replace("{sailingName}", entity.SailingName))) {
//do something
}
4) last but not least, use the standard resx files to add the required resource strings.
In fact I discovered pretty soon that many strings of the presentation layer were specified inside the js file, defining the angular app, controller, directive,....
So my first thought was to create a specific handler in order to generate the javascript at runtime so that I would have the capability to use the native localization management of ASP.NET or DotNetNuke.
IMHO the handler would have as many cons than pro, or even worst; for example, every js file would have been addressed by the unique handler, breaking the easy file organization of each DNN module or ascx control, ...: much work for a small problem.
So I passed to another approach:
why not concentrate all the strings to localize in a js object inside the ascx file?
the Angular.JS app (controller/directive,...) would be kept in a separate pure js file, with the capability to access the variable once on the client's browser.
The solution is composed by:
1) a method to run on load, in a base class of the module (or User control), with a couple of properties override-able in the specialized module class.
protected void LoadResourcesToJavascript()
{
if (this.ResourceKeysToJavascript.Count() > 0)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("var " + this.ResourceJSVariableName + " = {};\n");
foreach (String s in this.ResourceKeysToJavascript)
{
sb.Append(this.ResourceJSVariableName + "." + s + "= '" + Localization.GetString(s + ".Text", LocalResourceFile) + "';\n");
}
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), this.ResourceJSVariableName + "Resources", sb.ToString(), true);
}
}
protected virtual List
{
get
{
return new List
}
}
protected virtual String ResourceJSVariableName
{
get
{
return this.ID;
}
}
Note: I use the DNN method to get the localized string. Change it in case of standard ASP.NET project.
Note: The javascript variable name is the control's ID, but it can be specialized in the inherited module class.
2) in the inherited module / user control specialize the ResourceKeyToJavascript list with the resource string required in the javascript.
protected override List
{
get
{
return new List
"ConfirmRemoving",
"SailingName",
"Types",
"UnableToFindFriend",
"Saved",
"Error"};
}
}
3) in javascrpit file use the variable name (ASP.NET control's ID) to access the single resource strings:
var str = CrewMemberCollectionV2View.ConfirmRemoving;
if (confirm(str.replace("{sailingName}", entity.SailingName))) {
//do something
}
4) last but not least, use the standard resx files to add the required resource strings.