为LightSwitch HTML客户端添加签名

[原文发表地址] Adding a Signature Control to the LightSwitch HTML Client

[原文发表时间] 24 Apr 2013 8:02 AM

LightSwitch 是关于快速创建业务解决方案 – 定义你的数据模型&业务规则和利用一套内嵌的控件以可视化的方式创建屏幕。它完成了所有枯燥的工作这样你就可以精力集中在应用程序的真正价值上。但是LightSwitch同样允许各种自定义化,所以你不会遇到不知名的“玻璃天花板”。当团队打算建立LightSwitch HTML 客户端时,他们需要保证可扩展的模型是相当简单的,并与网页开发人员建立解决方案的方式一致。

对于Silverlight 客户,扩展的作者必须了解一系列的LightSwitch的可扩展性模型以便提供的扩展易于LightSwitch开发用户使用。在Visual Studio Galllery中关于LightSwitch的扩展 (即为签名控件)超过100种(还在增长)。但是对于HTML客户端,我们需要利用已有的大量的网页生态系统,那样添加自定义就像查找JavaScript类库并添加到你的应用程序一样简单。

团队成员已经写了很多关于在LightSwitch中混合自定义控件和数据绑定的文章。这儿有几个:

特别地,最后一篇来自Joe的文章极大地帮助了我。除了其他事情外,它描述了HTML 客户端的2个UI定制的挂钩-- renderpostRender事件。如果你需要修改LightSwitch创建的DOM元素(例如控件),可以使用postRender事件。它允许你添加元素就像添加CSS类或者其他的DOM属性。但是,如果你想要自己完全掌控显示的话,你可以通过使用LightSwitch自定义控件元素的render事件来实现。

LightSwitch是基于jQueryjQueryMobile创建的单页面应用程序(SPAs),因此有相当多的插件供LightSwitch使用。具体使用哪一个完全依赖于你需要给用户提供什么或者设备需要支持什么。在这里,我想给你展示一个快速的基于jSignature插件的混合签名控件的方法。

你可以在从这里下载完整的示例代码。

添加类库到你的LightSwitch项目中

第一步是获取你所需的控件。通过在Visual Studio中检索网页,查找目录,请求朋友,浏览NuGet,或者(天都不会答应的)自己写一份!你需要保证添加到应用程序中的任何自定义代码都能正常工作。jSignature有一个在线演示, 在做之前,你可以在你想要支持的设备上测试一下其是否正常工作。据说这个特殊的类库能够在许多设备上正常工作,其拥有很好的输入/输出特性,和良好的文档,这就是选择这个来举例的原因。

一旦你下载jSignature, 解压ZIP文件。打开你的LightSwitch工程,轻击Solution Explorer中的File View选项, 将jSignature.min.js类库拖到你的HTML客户端项目下的Script文件夹中。

image

接下来打开default.htm,添加引用脚本:

image

现在你已经准备好在你的LightSwitch应用中使用签名控件了。

添加自定义控件

为这个例子,我已经建立了简单的测试数据模型来追踪工作顺序。一旦雇员完成一个工作指令,他们需要签名。在LightSwitch中有许多方法来存储jSignature数据。jSignature支持许多类型的格式,详情请参考文档。针对这个例子,我将展示如何把它存储为图片业务类型的图片,以及存储为能够重新载入到jSignature控件中的被压缩的base30字符串。

所以我们的数据模型看起来像这样的。请注意我们自定义签名控件将要使用的2个字段,SignatureImage和SignatureVector。为保险起见,我将SignatureVector的长度设为2000, 但我认为大部分的签名不需要这么多的空间。

image

接下来我们将要添加一些与这些字段相关的Add/Edit Details屏幕。添加一个新的屏幕,选择Add/Edit Details, 将Screen Data设为WorkOrder。第一个命名为“SignWorkOrderImage”然后再添加一个为“SignWorkOrderVector”

image

现在在屏幕设计器中设计你所喜欢的内容树。对于SignWorkOrderImage屏幕,我在屏幕上添加了2次SignatureImage,其中一个将作为自定义控件。有不少方法可以添加自定义控件到屏幕中。如果你的控件不是针对特别的字段的话,在屏幕设计器的上部点击“Add Layout Item”,选择“Custom Control”, 然后你可以指定 “screen”作为绑定路径

但是,由于我们的绑定路径将要作为SignatureImage字段,只须在树中选择内容项,将它改为“Custom Control”

image

接下来将这2个签名控件的高度和宽度设为“Fit to Content”

image

同样将自定义控件的显示名称设为一些相对比较有意义的, 如“SIGN HERE:”。 所以SignWorkOrderImage屏幕的内容树看起来就这样。

image

类似的,对于SignWorkOrderVector屏幕,我们将要处理SignatureVector字段。对于测试,我想真实的看到vector数据,所以我在自定义控件下添加一个文本框来显示。所以内容树看起来就这样。

image

接下来我们需要在自定义控件的render事件中编写一些代码

将签名当作图片来使用

每一个控件类库是不一样的,所以在你编写代码来操作它之前你需要掌握控件本身的功能。但是一旦你按照演示完成的话,就很容易的了解这个特殊控件了。

关于LightSwitch你需要唯一记住的是,我们在our_render方法内看到的DOM并不是“真正的”DOM—这个DOM在jQueryMobile扩展之前就已经存在。正因为如此,我们需要等待直到DOM完全显示出来,这样我们就可以初始化控件和更改挂钩通知。Joe教会我们如何做到这点通过使用setTimeout()功能。

传递的是我们使用的(内容项)DOM元素(元素)和数据项。第一个创建的控件是ID为“signature”的<DIV>元素,并将它添加到DOM中。接着在setTimeout功能中,我们可以初始化控件和更改监听器挂钩。为了从jSignature控件中获取以图片形式的数据,我们调用getData并指定期望返回的类型。这个方法将返回一个包含指定类型和实际图片数据的数组(例如: img[1]

 myapp.SignWorkOrderImage.Signature_render = function (element, contentItem) {
  
     //Create the control & attach to the DOM
     var sig = $("<div id='signature'></div>");
     sig.appendTo($(element));
  
     setTimeout(function () {
         //Initialize and start capturing
         sig.jSignature();
  
         // Listen for changes made via the custom control and update the 
         // content item whenever it changes. 
         sig.bind("change", function (e) {
             var img = sig.jSignature("getData", "image");
             if (img != null) {
                 if (contentItem.value != img[1]) {
                     contentItem.value = img[1];
                 }
             }
         });
     }, 0);    
 };

我们同样可以在屏幕上添加一个按钮来清除签名 – 仅仅指定这段代码到按钮的执行方法中。

 myapp.SignWorkOrderImage.ClearSignature_execute = function (screen) {
     // Write code here.
     $("#signature").jSignature("reset");
 };

所以当我们运行这个屏幕时,我们可以看到签名控件,当我们执行每个操作时,我们的图片控件就更新了。如果我们保存它,它将会当作图片保存到数据库中。

image

将签名当作向量使用

将图片直接保存到数据库中是快速和便利的,但jSignature控件文档提示不支持Android旧版本。同时图片不能很好的按比例增减。所以将图片数据保存为向量或者别的可能会更好,这样以后就能够重新显示。就像我之前提到的,有很多格式可供选择,即使是SVG和Base64格式。与其在LightSwitch中将数据作为图片业务类型保存,不如改用标准的二进制会更好。

但是由于jSignature提供的base30格式是最紧凑的,我们将在下一个例子中使用。这个格式同样允许当打开屏幕的时候加载到jSignature控件中。

 myapp.SignWorkOrderVector.Signature_render = function (element, contentItem) {
  
     //Create the control & attach to the DOM
     var sig = $("<div id='signature' ></div>");
     sig.appendTo($(element));
  
     setTimeout(function () {
         //Initialize control and set initial data 
         sig.jSignature();
         if (contentItem.value != null) {
             sig.jSignature("setData", "data:" + contentItem.value);
         }
  
         // Listen for changes made via the custom control and update the 
         // content item whenever it changes. 
         sig.bind("change", function (e) {
             var data = sig.jSignature("getData", "base30");
             if (data != null) {
                 data = data.join(",");
                 if (contentItem.value != data) {
                     contentItem.value = data;
                 }
             }
         });
     }, 0);   
 };

当我们运行这个屏幕是你可以看到签名的负载要小很多。当再次打开的时候,我们同样可以看到控件的数据加载

image

总结

就是这些了!正如你看到的,添加自定义的UI只需要一点点的JavaScript知识和了解LightSwitch如何显示DOM。事实上,我是通过LightSwitch来学习JavaScript & jQuery, 我认为我现在已经有足够的知识来危险实现 :-)

记住并不是所有的设备都支持所有的控件,所以你的实际情况或许有所不同。但是希望我展示了如何轻松的自定义LightSwitch HTML客户端

玩得愉快!