【问题标题】:How to implement templating on UWP/UAP如何在 UWP/UAP 上实现模板化
【发布时间】:2016-08-24 14:17:34
【问题描述】:

我需要根据 UWP/UAP 项目中的一些模型生成 HTML - 完全用 C# 编写。

问题是没有预先存在的模板引擎(我真的不想从头开始编写一个)与该平台兼容。我查找了一些最受欢迎的替代方案,但没有一个能开箱即用。

对于我面临的这个实质性问题,您建议的解决方案是什么?我曾考虑移植一个可用的开源库,但我不确定是否值得。

我对自以为是的答案或模板引擎的建议(在 UAP 上不起作用)不感兴趣,只对解决 Windows 10 通用应用程序中的模板问题的最简单方法感兴趣。

【问题讨论】:

  • 这是一个广泛的问题。但我使用 mustache.github.io 和 javascript。
  • @ErkanDemirel -- 问题不在于广泛性。对图书馆等外部资源的推荐请求完全是题外话。
  • @roryap 这个网站上有很多关于模板引擎的问题(投票率很高)。
  • @KonradMorawski -- 当然,它们将是关于实质性问题或问题的问题,而不是请求建议。您的第一句话“您知道任何模板引擎库吗”清楚地表明这是题外话。
  • @KonradMorawski -- 这是“关闭原因”的直接引用:要求我们推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题是题外话对于 Stack Overflow,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决该问题所做的工作。

标签: c# .net windows-10 template-engine windows-10-universal


【解决方案1】:

如果您正在开发,使用HTML/JavaScript,您可以使用内置的WinJS 库在HTML 中进行模板化。微软还为AngularReactKnockout 创建了许多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#,有两种选择:

  1. 继续寻找库或自己推动它将进行此类转换,或
  2. 围绕 webview 控件构建一个包装器,它可以为您使用现有的库。

在第二种情况下应该很容易: 1)您应该使用您在 JavaScript 中选择的任何库来实现从 JSON 到 HTML(带模板)的转换器,它应该可用于从外部上下文(全局函数或对象)调用。这样的函数应该以 JSON 字符串的形式接收数据并返回一个字符串(例如来自 innerHTML)。 2) 使用带有 InvokeScriptAsync/ScriptNotify 事件的标准技术让 WebView 控件在 C# 和 JS 环境之间传输数据。您实际上不需要在页面内显示 WebView。只需将其用作 JS 执行的环境即可访问相应库所需的 DOM。

下面是 WinJS 的代码示例: HTML/JS. 带有 WinJS 库的 template.html 文件。全局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 对象,而不仅仅是文本。

【讨论】:

  • 我使用 C#,所以我将问题标记为 C#
  • 我建议把它自己放在问题中,因为它仍然不清楚。
  • 更新了我的答案。
  • 好的,我更新了问题以消除歧义。感谢您的见解。您会建议任何特定的 JavaScript 库吗?我觉得这是可能的,虽然有点粗鲁的 Goldberg 式,C# 到 Json,Json 到 JavaScript,然后 HTML 来自“假”WebView ......如果没有更好的选择,它仍然可能是我会做的。 +1 提供更多选择。
  • 任何轻量级库都应该适合你。我用 WinJS 添加了一个示例。
猜你喜欢
  • 2020-08-01
  • 2020-07-27
  • 1970-01-01
  • 1970-01-01
  • 2017-02-18
  • 2017-07-02
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多