如何:使用代码修改 HTML 屏幕?
如何:使用代码修改 HTML 屏幕
Visual Studio 2013
原文章:http://msdn.microsoft.com/zh-cn/library/jj733572.aspx
设计 LightSwitch 应用程序的 HTML 屏幕时,应主要使用设计器和工具窗口,但你也可以使用代码通过特定方法修改这些屏幕。 通过使用 LightSwitch JavaScript API,你可以执行以下与数据相关的任务。
创建数据输入屏幕后,你可能需要使用默认值填充一些字段。 例如,你可以将日期字段的默认值设置为当前日期。 若要在面向某个实体的任何“添加/编辑详细信息”屏幕中设置默认值,请在该实体的 created 方法中编写代码。
设置默认值
在实体设计器中的“透视”栏上,选择“HTMLClient”选项卡。
在“编写代码”列表中,选择“已创建”。
在代码编辑器中,通过将代码添加到 created 方法来设置初始值:
entity.OrderDate = new Date(); entity.OrderStatus = \'New\';
为实体创建的任何“添加/编辑详细信息”屏幕都将自动显示这些默认值。
由于某些移动设备的屏幕空间有限,你可能需要设置数字的格式来降低显示精度。 以下示例演示如何设置数字的格式,使其存储为 Double 以便仅显示小数点后两位数。
设置数字的格式
在“屏幕设计器”中,选择要进行格式设置的数字的节点。
在工具栏上,打开“编写代码”列表,然后选择 postRender 方法。
在代码编辑器中,为 postRender 方法添加以下代码:
contentItem.dataBind("value", function (value) { if (value) { $(element).text(value.toFixed(2)); } });
若要更改日期的显示格式,你必须使用 JavaScript 库,如 Moment.js。 将库添加到项目中后,在 default.htm 文件中添加引用,然后在“Render”或“postRender”方法中编写代码。
添加库
在“解决方案资源管理器”中,打开“HTMLClient”节点的快捷菜单,然后选择“管理 NuGet 包”。
在“管理 NuGet 包”对话框中,选择”“联机”节点。
在“联机搜索”文本框中,输入“moment.js”。
选择“安装”按钮安装 Moment.js 库,然后选择“关闭”按钮。
添加引用
在“解决方案资源管理器”中,展开“HTMLClient”节点,然后打开“default.htm”文件。
在代码编辑器中,将以下脚本标记添加到最后一个 </script> 标记之后:
<script type="text/javascript" src="Scripts/moment.js" charset="utf-8"></script>
设置日期的格式
在“解决方案资源管理器”中,打开要在其中设置日期格式的屏幕。
在屏幕设计器中,选择要在其中应用日期格式的节点。
在工具栏上,打开“编写代码”列表,然后选择 postRender 方法。
在代码编辑器中,为 postRender 方法添加以下代码:
contentItem.dataBind("value", function (value) { if (value) { $(element).text(moment(value).format("DD/MM/YYYY")); } });
“ListView”控件的外观由级联样式表 (CSS) 决定,且样式非常复杂。 你可以使用 postRender 方法更改代码中的颜色,而不是尝试编辑 CSS。 请注意,你不能更改“ListView”本身的样式,但可以通过其父级(“RowTemplate”)更改每个“列表项”的样式。 每个“列表项”都定义了 background-image,因此你需要在应用新的“背景色”之前指定 background-image。
更改颜色
在屏幕设计器中,选择列表的“行布局”(或“列布局”)节点。
在“属性”窗口中,选择“编辑 PostRender 代码”链接。
在代码编辑器中,为 postRender 方法添加以下代码:
$(element).parent().css({ "background-color": "green", "background-image": "none", color: "yellow" });
用于在屏幕上显示必填字段的通用约定旨在提供视觉线索,如使用不同的字体颜色并在字段名旁边显示星号。
突出显示必填字段
在屏幕设计器中,选择要标记为必填的字段。
在“属性”窗口中,选择“编辑 PostRender 代码”链接。
在代码编辑器中,为 postRender 方法添加以下代码:
$(element).parent().css(\'color\', \'red\'); $(element).parent().find("label")[0].innerHTML += " *"
通过提供自定义验证逻辑,你可以确保仅将有效数据保存到数据源中。 你可在 beforeApplyChanges 方法中添加验证代码,当用户点击“添加/编辑”屏幕上的“保存”按钮时将调用此方法。 在下面的示例中,系统会发出消息,告知在“ContactName”字段中输入感叹号的用户不允许在此字段中输入该字符。
验证数据
在“屏幕设计器”中的“编写代码”列表中,选择“beforeApplyChanges”。
在代码编辑器中,添加以下代码,将 Contact 替换为实体的名称,并将 ContactName 替换为要验证的字符串字段的名称:
if (screen.Contact.ContactName.indexOf(\'!\') != -1) { screen.findContentItem("ContactName").validationResults = [ new msls.ValidationResult( screen.Contact.details.properties.contactName, "Contact Name cannot contain the character \'!\'.") ]; return false; }
LightSwitch 提供的内置方法可用于在 HTML 屏幕上添加和编辑项目,但不会删除它们。 你可轻松创建你自己的用于从屏幕或弹出窗口中删除项的方法。
删除某项
在“屏幕设计器”中的工具栏上,选择“添加数据项”按钮。
在“添加数据项”对话框中,选择“方法”选项按钮,然后输入方法的名称。
打开该方法的快捷菜单,然后选择“编辑 Execute 代码”。
在代码编辑器中,添加以下代码,将 myScreen 替换为屏幕的名称,并将 customers 的两个实例替换为实体的名称:
myapp.MyScreen.DeleteSelected_execute = function (screen) { screen.getCustomers().then(function (customers) { customers.deleteSelected(); }); };
可在显示实体的任何屏幕或弹出项的“添加按钮”对话框中使用此方法。
如果你显示模式对话框,则可允许用户从列表中选择项,这可通过添加屏幕查询和弹出项来轻松实现。 在此示例中,你有一个名为“AddOrders”的“添加/编辑详细信息”屏幕,该屏幕基于一个“OrderDetails”实体和另一个名为“Products”的相关实体。
创建模式选取器
在“屏幕设计器”中的工具栏上,选择“添加数据项”按钮。
在“添加数据项”对话框中,选择“查询”选项按钮,然后从列表中选择“Products”。
“Products”查询显示在“屏幕设计器”的左窗格中。
在内容树中,打开“弹出项”节点的快捷菜单,然后选择“添加弹出项”。
在“添加”列表中,选择“Products”。
在工具栏上的“编写代码”列表中,选择“已创建”。
在“代码编辑器”中,向“已创建”方法添加以下代码:
myapp.AddOrders.created = function (screen) { screen.findContentItem("Products").dataBind("value.selectedItem", function (newValue) { if (newValue !== undefined && newValue !== null) { //Whenever selectedItem for Products changes, update the Product value on the main page screen.Order_Detail.setProduct(screen.Products.selectedItem); //Close popup, if one is open. screen.closePopup(); } }); };
在“屏幕设计器”中,打开“命令栏”节点的快捷菜单,然后选择“添加按钮”。
在“添加按钮”对话框中,选择“确定”按钮。
(可选)若要清除字段,请添加带以下代码的屏幕方法:
myapp.AddOrders.Clear_execute = function (screen) { //Clear the selection for Product. (Useful for 0...1 to many relationships.) screen.Order_Detail.setProduct(undefined); };
弹出项的默认位置在屏幕底部;宽屏幕的右下角。 在大屏幕上,该位置可能会导致弹出项难以被发现。 以下示例将弹出项放置在屏幕的中心,使其更引人注目。
使弹出项居中
在屏幕设计器中,选择启动弹出项的按钮节点。
在“属性”窗口中,在“操作”下选择“点击”链接。
在“编辑点击操作”对话框中,选择“自行编写方法”选项按钮,对其命名,然后选择“确定”按钮。
在“属性”窗口中,选择“编辑 Execute 代码”链接。
在代码编辑器中,为 execute 方法添加以下代码:
// Note:If using JQuery Mobile 1.3 (or higher) use // "popupcreate" rather than "popupbeforeposition" $(window).one("popupbeforeposition", function (e) { $(e.target).popup({ positionTo: "window" }); }); // Show the Popup screen.showPopup("Popup1");
通过显示消息框,你可以为用户提供选择,然后根据用户的选择执行操作。 以下示例显示一个不同的消息以响应“是/否/取消”消息框中的每个选项。 在你自己的代码中,可以将警报代码替换为用于执行你自己的操作的代码,例如,根据用户的选择显示不同的屏幕。
显示消息框
在“屏幕设计器”中,打开“命令栏”节点的快捷菜单,然后选择“添加按钮”。
在“添加按钮”对话框中,选择“自行编写方法”选项按钮,然后将该方法命名为 ShowMessageBox。
在代码编辑器中,为 ShowMessageBox_execute 方法添加以下代码:
msls.showMessageBox("Please choose the appropriate button", { title: "This is a message box", buttons: msls.MessageBoxButtons.yesNoCancel }).then(function (result) { if (result === msls.MessageBoxResult.yes) { alert("Yes button was chosen"); } else if (result === msls.MessageBoxResult.no) { alert("No button was chosen"); } else if (result === msls.MessageBoxResult.cancel) { alert("Please choose either Yes or No"); } });
你可能需要基于设计时不可用的信息来更改屏幕标题,例如,当前选择的客户的名称。 以下代码示例动态显示名为“ViewCustomer”的屏幕的屏幕标题,它基于名为“Customer”的实体。
设置屏幕标题
在“屏幕设计器”中的“编写代码”列表中,选择“已创建”。
在“代码编辑器”中,向“已创建”方法添加以下代码:
myapp.ViewCustomer.created = function (screen) { var name; name = screen.Customer.CompanyName; screen.details.displayName = "Information about: " + name; };
默认情况下,你的项目名称在初始屏幕和标题栏或浏览器选项中显示为应用程序的标题。 你可通过修改项目的 default.htm 文件来指定不同的标题。
更改标题
在“解决方案资源管理器”中的“HTMLClient”节点下,打开“default.htm”文件的快捷菜单,然后选择“打开”。
在代码编辑器中,查找 <title> 元素,并将现有值替换为你的标题。
此字符串将显示在标题栏或浏览器选项卡中。
查找 <div> 元素,并将现有值替换为你的标题。
此字符串将显示在初始屏幕中。
你经常需要基于特定条件来启用或禁用按钮。 例如,你可能会对某些用户禁用屏幕启动按钮,或可能仅在需要某个值时启用添加按钮。 第一个示例演示如何通过从代码设置 IsEnabled 属性来禁用按钮。
第二个示例演示一个基于 CanExecute 方法的双步方法。 数据在 LightSwitch 中是异步加载的,但按钮的 CanExecute 方法是同步的。 因此,不能基于单个传递中加载的数据启用按钮,但可以通过使用 IsLoaded 属性实现双步方法。
使用 IsEnabled 属性禁用按钮
在“屏幕设计器”中的工具栏上,选择“添加数据项”按钮。
在“添加数据项”对话框中,选择“方法”选项按钮,然后输入方法的名称。
打开该方法的快捷菜单,然后选择“编辑 Execute 代码”。
在代码编辑器中,添加以下代码,将 MyButton 替换为按钮的名称:
screen.findContentItem("MyButton").isEnabled = false;
当需要禁用或启用按钮时,可从代码调用方法。
提示 若要隐藏或显示按钮,请使用 IsVisible 属性。
使用 IsLoaded 属性启用按钮
在“屏幕设计器”中的工具栏上,选择“添加数据项”按钮。
在“添加数据项”对话框中,选择“方法”选项按钮,然后输入方法的名称。
打开该方法的快捷菜单,然后选择“编辑 CanExecute 代码”。
在代码编辑器中,添加以下代码,将 Orders 替换为实体的名称,将 Photo 替换为实体属性的名称,并将 GetPhoto 替换为要执行的功能的名称:
var result = false; if (!screen.Order.details.properties.Photo.isLoaded) { screen.Order.getPhoto(); } else { screen.Order.getPhoto().then(function (ph) { result = !ph; }); } return result;
创建屏幕时调用 CanExecute 方法。 在第一次通过中,代码将验证 Photo 属性是否已加载。 如果未加载,则代码将加载数据且函数终止。 加载数据后,会再次调用 CanExecute 方法,并且 else 分支将运行。 此时会同步运行 GetPhoto 函数,因为已加载数据,这可确保获得有效结果。
你可将一个屏幕的更新保存到多个数据源中,方法是使用 WinJs Promise 对象来自定义内置的“保存”命令。
保存到多个数据源
在“屏幕设计器”中的工具栏上,选择“编写代码”按钮。
在代码编辑器中,将下列代码添加到 onsavechanges 方法,并将 NorthwindData 和 ApplicationData 替换为数据源的名称:
myapp.onsavechanges = function (e) { var promises = []; promises.push(myapp.activeDataWorkspace.NorthwindData.saveChanges()); promises.push(myapp.activeDataWorkspace.ApplicationData.saveChanges()); e.detail.promise = WinJS.Promise.join(promises); };
如果需要更多数据源,你可以为每个源添加一个 promises.push… 行。
从列表项导航到“视图”或“编辑”屏幕后,默认行为是将焦点返回到列表中的第一个项。 通常需要将焦点返回到启动屏幕的列表项,尤其是在需要滚动的大型列表中。 你可以通过绑定到 Custom Method 并使用 JQuery scrollTop 方法来修改行为以返回到之前选择的列表项。
设置焦点
在屏幕设计器中,选择要在其中实现此行为的“列表”节点。
在“属性”窗口中,在“操作”下选择“点击”链接。
在“编辑点击操作”对话框中,选择“自行编写方法”选项按钮,然后选择“确定”按钮。
在“属性”窗口中,选择“编辑 Execute 代码”链接。
在代码编辑器中,为 Tap_execute 方法添加以下代码:
var scrollTopPosition = $(window).scrollTop(); myapp.showViewOrder(screen.Orders.selectedItem, { afterClosed: function () { $(window).scrollTop(scrollTopPosition); } });
屏幕设计器提供了有限数目的用于显示数据的控件,但你可以轻松添加 JQuery Mobile 控件以获得更丰富的 UI 体验。 JQuery Mobile Foundation 库包含多种多样的控件,这些控件针对移动设备进行了优化,包括滑块、单选按钮、复选框及更多控件。 请参见 JQuery Mobile 框架。
以下示例添加了一个用于在文本框控件中设置数值的滑块控件。
添加滑块控件
在“屏幕设计器”中,选择数值字段的节点。
将“文本框”控件替换为“自定义控件”。
在“属性”窗口中,将“宽度”属性设置为“根据容器进行拉伸”。
选择“编辑 Render 代码”链接,然后在“代码编辑器”中,将以下代码添加至 render 方法:
createSlider(element, contentItem, 0, 100);
说明 滑块的默认值介于 0 和 100 之间。 如有必要,可将其替换为适用于应用程序的值。
将以下函数添加到屏幕的代码文件中:
function createSlider(element, contentItem, min, max) { // Generate the input element.var value = contentItem.value || 0, $element = $(element) .append(\'<input type="range" min="\' + min + \'" max="\' + max + \'" value="\' + value + \'"/>\') .on("slidestop", function () { contentItem.value = $element.find("input").val(); });
显示 Boolean 值的“FlipSwitch”控件仅提供两个显示文本选项:“是”/“否”或“开”/“关”。 若要显示不同的值,你可以创建基于“FlipSwitch”控件的自定义控件。 以下示例创建 True/False 控件。
自定义控件
在“屏幕设计器”中,选择 Boolean 字段的节点。
将控件类型从“FlipSwitch”更改为“自定义控件”。
在“属性”窗口中,选择“编辑 Render 代码”链接。
在代码编辑器中,为 render 方法添加以下代码:
createBooleanSwitch(element, contentItem);
将以下函数添加到屏幕的代码文件中:
function createBooleanSwitch(element, contentItem) { var $flipSwitch = $(\'<select data-role="slider"></select>\').appendTo($(element)); $(\'<option value="false">false</option>\').appendTo($flipSwitch); $(\'<option value="true">true</option>\').appendTo($flipSwitch); // set select value to match the original contentItem.value $flipSwitch.val((contentItem.value) ? "true" : "false"); // add listener to update contentItem\'s value if slider changes $flipSwitch.change(function () { contentItem.value = ($flipSwitch.val() == "true"); }); // visually refresh the slider. $flipSwitch.slider().slider("refresh"); };
说明 你可能需要将“宽度”属性的值设置为 150 或更大以正确显示控件。
Boolean 数据类型的默认控件类型是“FlipSwitch”控件,但你可以使用自定义控件轻松替换“CheckBox”。
显示 CheckBox
在屏幕设计器中,选择 Boolean 字段的节点,然后将控件类型从“FlipSwitch”更改为“自定义控件”。
在“属性”窗口中的“高度”部分中,选择“最小值”并输入 100。由于“CheckBox”控件高于标准的“TextBox”控件,因此必须这样做。 如果你的窗体使用其他控件类型,则可能需要调整此值。
在“常规”部分中,选择“编辑 Render 代码”链接。
在代码编辑器中,为 render 方法添加以下代码:
// Create the checkbox and add it to the DOM. var checkbox = $("<input type=\'checkbox\'/>") .css({ height: 20, width: 20, margin: "10px" }) .appendTo($(element)); // Determine if the change was initiated by the user. var changingValue = false; checkbox.change(function () { changingValue = true; contentItem.value = checkbox[0].checked; changingValue = false; }); contentItem.dataBind("value", function (newValue) { if (!changingValue) { checkbox[0].checked = newValue; } });
若要在“添加/编辑”屏幕上显示必填字段的“CheckBox”,你还需要设置控件的初始值,否则用户可能会收到验证错误。
设置初始值
在实体设计器中的“透视”栏上,选择“HTMLClient”选项卡。
在“编写代码”列表中,选择“已创建”。
在代码编辑器中,通过将代码添加到 created 方法来设置初始值:
entity.FieldName = new Boolean(); entity.FieldName = \'true\';
将 Boolean 替换为 FieldName 字段的名称。 若要将控件初始化为未选中状态,请将 false 替换为 true。
自定义控件基于 JQuery Mobile 框架,并且该框架自动设计了某些控件的样式,以使这些控件为在移动设备上的显示而优化。 在某些情况下,你可能需要重写外观以提供更传统的样式,例如,JQuery Mobile 按钮比传统按钮控件大。 你可使用 data-role="none" 特性来重写样式并显示常规按钮。
应用特性
在屏幕设计器中,选择自定义控件节点。
在“属性”窗口中,选择“编辑 Render 代码”链接。
将以下代码添加到 render 方法中:
var $element = $(element); var $textbox1 = $(\'<input type="text" data-role="none"/>\'); $element.append($textbox1);
说明 将 textbox1 替换为自定义控件的名称,并将 “text” 替换为控件类型。
你可通过使用地理位置 API 来确定特定设备的当前位置,以启用映射和基于接近程度的方案。 以下示例确定实体的坐标,该实体名为 MyLocation 且具有名为 Latitude 和 Longitude 的 Double 类型的属性。
获得位置
在“屏幕设计器”中的工具栏上,选择“编写代码”按钮。
在代码编辑器中,添加以下方法:
myapp.AddEditMyLocation.GetGeolocation_execute = function (screen) { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(function (pos) { screen.MyLocation.latitude = pos.coords.latitude.toString(); screen.MyLocation.longitude = pos.coords.longitude.toString(); }); } else { alert("Geolocation not supported"); } };
若要轻松添加映射功能,你可以从 Bing 地图 SDK 中获取免费的开发人员密钥,然后创建可调用 Bing 地图 Web 服务的自定义控件。
以下示例将客户位置显示为地图上的图钉,并且你可以通过点击图钉来显示有关每个客户的详细信息。 此示例要求将名为“BrowseCustomers”的屏幕附加到具有“地址”、“城市”和“国家/地区”字段的“Customers”实体,并且名为“详细信息”的弹出项必须在“BrowseCustomers”屏幕上。