如何在 UWP/UAP 上实施模板
How to implement templating on UWP/UAP
我需要根据 UWP/UAP 项目中的某些模型生成 HTML - 完全用 C# 编写。
问题是没有任何预先存在的模板引擎(我真的不想从头开始编写一个)与该平台兼容。我查了几个最流行的替代品,none 开箱即用。
对于我面临的这个实质性问题,您建议的解决方案是什么?我考虑过移植一个可用的开源库,但我不确定是否值得付出努力。
我对固执己见的答案或模板引擎的建议(在 UAP 上不起作用)不感兴趣,只对解决 Windows 10 通用模板问题的最简单途径感兴趣应用程序。
如果您正在使用 HTML/JavaScript
进行开发,您可以使用内置的 WinJS
库在 HTML
中进行模板化。此外,Microsoft 还为 Angular
、React
或 Knockout
创建了一些 adapters,以便在 UWP
应用程序中使用它们。
通常大多数 JavaScript
代码应该都能正常工作,您唯一应该考虑的是 security limitations 在嵌入 iframe 或外部脚本时。要绕过此类限制,您应该更新所用库的逻辑或使用 execUnsafeLocalFunction
方法手动强制执行。
MSApp.execUnsafeLocalFunction(function() {
var body = document.getElementsByTagName('body')[0];
body.innerHTML = '<div style="color:' + textColor + '">example</div>';
});
==
更新:
对于 C#,有两个选项:
- 继续寻找库或自己推动它进行这种转换,或者
- 围绕 webview 控件构建一个包装器,这将使用现有的库为您完成。
第二种情况应该很简单:
1) 您应该使用您在 JavaScript 中选择的任何库实现从 JSON 到 HTML(带模板)的转换器,它应该可用于从外部上下文(全局函数或对象)调用).这样的函数应该接收数据作为 JSON-string 和 return 字符串(例如来自 innerHTML)。
2) 使用带有 InvokeScriptAsync/ScriptNotify 事件的标准技术为 WebView 控件在 C# 和 JS 环境之间传输数据。您实际上不需要在页面内显示 WebView。只需将其用作 JS 执行的环境,即可访问相应库所需的 DOM。
这是 WinJS 的代码示例:
HTML/JS. template.html 包含 WinJS 库的文件。全局 js 函数:
function convertFromJSON2HTML(jsonString, templateHTML) {
var templateEl = document.createElement("div");
templateEl.innerHTML = templateHTML;
var jsonData = JSON.parse(jsonString);
if (WinJS != undefined) {
var template = new WinJS.Binding.Template(templateEl);
//promise
template.render(jsonData).done(function(output) {
window.external.notify(output.innerHTML);
});
} else {
// catch error
}
}
C#代码
public async Task<string> GenerateTemplate(string jsonData, string template)
{
var webView = new WebView();
webView.Source = new Uri("ms-appx-web:///HTML/template.html");
webView.DOMContentLoaded += async (o, e) =>
{
await webView.InvokeScriptAsync("convertFromJSON2HTML", new string[] { jsonData, template });
};
string output = "";
// Simple trick to convert event result to async result
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
webView.ScriptNotify += (o, e) =>
{
output = e.Value;
tcs.SetResult(true);
};
await tcs.Task;
return output;
}
用法。 我在这里使用 WinJS 风格的模板:
var result = await GenerateTemplate("{\"x\":\"test\"}","<p data-win-bind='textContent:x'></p>");
resultBox.Text = result;
另外,为了简化通信,我建议使用 AddAllowedWebObject 方法在两个环境之间传递 WinRT 对象,而不仅仅是文本。
我需要根据 UWP/UAP 项目中的某些模型生成 HTML - 完全用 C# 编写。
问题是没有任何预先存在的模板引擎(我真的不想从头开始编写一个)与该平台兼容。我查了几个最流行的替代品,none 开箱即用。
对于我面临的这个实质性问题,您建议的解决方案是什么?我考虑过移植一个可用的开源库,但我不确定是否值得付出努力。
我对固执己见的答案或模板引擎的建议(在 UAP 上不起作用)不感兴趣,只对解决 Windows 10 通用模板问题的最简单途径感兴趣应用程序。
如果您正在使用 HTML/JavaScript
进行开发,您可以使用内置的 WinJS
库在 HTML
中进行模板化。此外,Microsoft 还为 Angular
、React
或 Knockout
创建了一些 adapters,以便在 UWP
应用程序中使用它们。
通常大多数 JavaScript
代码应该都能正常工作,您唯一应该考虑的是 security limitations 在嵌入 iframe 或外部脚本时。要绕过此类限制,您应该更新所用库的逻辑或使用 execUnsafeLocalFunction
方法手动强制执行。
MSApp.execUnsafeLocalFunction(function() {
var body = document.getElementsByTagName('body')[0];
body.innerHTML = '<div style="color:' + textColor + '">example</div>';
});
== 更新:
对于 C#,有两个选项:
- 继续寻找库或自己推动它进行这种转换,或者
- 围绕 webview 控件构建一个包装器,这将使用现有的库为您完成。
第二种情况应该很简单: 1) 您应该使用您在 JavaScript 中选择的任何库实现从 JSON 到 HTML(带模板)的转换器,它应该可用于从外部上下文(全局函数或对象)调用).这样的函数应该接收数据作为 JSON-string 和 return 字符串(例如来自 innerHTML)。 2) 使用带有 InvokeScriptAsync/ScriptNotify 事件的标准技术为 WebView 控件在 C# 和 JS 环境之间传输数据。您实际上不需要在页面内显示 WebView。只需将其用作 JS 执行的环境,即可访问相应库所需的 DOM。
这是 WinJS 的代码示例: HTML/JS. template.html 包含 WinJS 库的文件。全局 js 函数:
function convertFromJSON2HTML(jsonString, templateHTML) {
var templateEl = document.createElement("div");
templateEl.innerHTML = templateHTML;
var jsonData = JSON.parse(jsonString);
if (WinJS != undefined) {
var template = new WinJS.Binding.Template(templateEl);
//promise
template.render(jsonData).done(function(output) {
window.external.notify(output.innerHTML);
});
} else {
// catch error
}
}
C#代码
public async Task<string> GenerateTemplate(string jsonData, string template)
{
var webView = new WebView();
webView.Source = new Uri("ms-appx-web:///HTML/template.html");
webView.DOMContentLoaded += async (o, e) =>
{
await webView.InvokeScriptAsync("convertFromJSON2HTML", new string[] { jsonData, template });
};
string output = "";
// Simple trick to convert event result to async result
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
webView.ScriptNotify += (o, e) =>
{
output = e.Value;
tcs.SetResult(true);
};
await tcs.Task;
return output;
}
用法。 我在这里使用 WinJS 风格的模板:
var result = await GenerateTemplate("{\"x\":\"test\"}","<p data-win-bind='textContent:x'></p>");
resultBox.Text = result;
另外,为了简化通信,我建议使用 AddAllowedWebObject 方法在两个环境之间传递 WinRT 对象,而不仅仅是文本。