一个完整的 Visual Studio LightSwitch 2013 HTML5 应用程序






4.89/5 (36投票s)
Visual Studio 2013 LightSwitch HTML 5 应用程序教程。
从这里下载项目:
在线演示:
- https://endtoendexample.lightswitchhelpwebsite.com/Client/default.htm
(使用您的用户名和密码,来自 http://LightSwitchHelpWebsite.com)
注意:您可以查看一篇关于为该应用程序创建报表的文章,地址是:
在本篇文章中,我们将使用 Visual Studio LightSwitch 创建一个端到端的 HTML 应用程序。目的是展示 LightSwitch 如何帮助您创建专业的业务应用程序,而这些应用程序可能需要开发人员数天才能完成。使用 LightSwitch,您可以在一小时内创建此类应用程序。
您可以在以下地址下载 LightSwitch: http://www.microsoft.com/visualstudio/en-us/lightswitch。此外,您还必须安装 Visual Studio 2013(或更高版本)以及 Office Developer Tools for Visual Studio 2013 – March 2014 Update(或更高版本)。
场景
在本例中,我们将负责创建一个满足以下要求的订单跟踪系统应用程序:
- 产品
- 添加产品
- 编辑产品
- 订单
- 添加订单
- 编辑订单
- 添加订单明细
- 编辑订单明细
- 删除订单明细
- 删除订单
- Business Rules
- 允许当前用户仅查看其订单
- 特点
- 显示用户的订单数量
- 显示订单的订单明细数量
该应用程序允许您创建 Products
(产品)列表。
Products
(产品)可以被编辑。
Orders
(订单)可以被创建。
一个 Order
(订单)包含多个 Order Details
(订单明细)。
一个 Order Detail
(订单明细)包含一个 Product
(产品),从可用 Products
(产品)列表中选择,以及一个 quantity
(数量)。
创建应用程序
打开 Visual Studio 并选择 文件,然后选择 新建项目。
创建一个新的 LightSwitch HTML 应用程序。
应用程序将被创建。
应用程序将显示在 解决方案资源管理器中。
在 Server
(服务器)项目中的 数据源 文件夹上右键单击,然后选择 添加表。
单击表名进行编辑。
将表名更改为 Product
(产品)。
此外,为该表添加 ProductName
(产品名称)和 ProductPrice
(产品价格)字段。
单击“保存”按钮保存该表。
创建一个 Order
(订单)表(包含上图中的字段)。
创建一个 OrderDetail
(订单明细)表(包含上图中的字段)。
创建关系
当表相关联时,您将始终希望建立关系。这允许最优化的 LightSwitch 应用程序构建。在创建查询时,定义了关系后,您只需键入一个句点(“.”)即可从一个实体遍历到另一个实体。这节省了大量编码工作并减少了编码错误。
在创建用户界面时,定义关系可以为您节省大量编码工作,因为 LightSwitch 可以自动将例如 Order Details
(订单明细)与其关联的 Order
(订单)关联起来。
单击 关系 按钮,在 OrderDetail
(订单明细)和 Product
(产品)表之间创建关系。
会出现一个框。选择 Product
(产品)作为到表,然后单击 确定(确保其他字段与上图匹配)。
您将看到已创建关系。您可以双击该线条来编辑关系。
再次单击 关系 按钮,并与 Order
(订单)表建立关系。
创建过滤器
我们需要实现的一项功能是只显示用户自己的订单(并允许管理员查看所有订单)。我们必须记住,所有 LightSwitch 应用程序 都通过 OData 公开所有数据,因此我们必须始终在服务器端代码中设置安全,而不仅仅是在客户端代码(例如 HTML 或 Silverlight LightSwitch 客户端)中。
我们需要做的第一件事是启用安全性。
接下来,我们打开 Orders
(订单)表,选择 编写代码,然后选择 Orders_Filter
。
为该方法使用以下代码
partial void Orders_Filter(ref Expression<Func<Order, bool>> filter) { // Only show the Orders for the current user filter = (x => x.UserName == this.Application.User.Name); }
所有访问此表的数据都将通过此过滤器。
设置默认值
考虑到我们必须在服务器端代码中设置所有与安全相关的内容,我们意识到使用当前用户的 UserName
(用户名)标记订单必须使用服务器端代码来设置,以防止 UserName
(用户名)被不正确地设置。
打开 Orders
(订单)表,选择 编写代码,然后选择 Orders_Inserting
。为该方法使用以下代码
partial void Orders_Inserting(Order entity) { // Set the Username entity.UserName = this.Application.User.Name; }
对 Orders_Updating
事件执行相同的操作。
稍后,我们也将使用客户端代码设置 UserName
(用户名),但服务器端代码将始终运行并覆盖任何客户端设置的值。
创建查询
我们需要实现的另一项功能是显示当前用户的订单数量。我们将创建一个稍后可以从客户端使用的查询。
右键单击 Orders
(订单)表,然后选择 添加查询。
通过单击标题并进行编辑,将查询命名为 OrdersForUser
(用户订单)。先保存它,然后选择 OrdersForUser PreprocessQuery
。
为该方法使用以下代码
partial void OrdersForUser_PreprocessQuery(ref IQueryable<Order> query) { // Only show the Orders for the current user query = query.Where(x => x.UserName == this.Application.User.Name); }
创建产品用户界面
我们首先创建一个屏幕,允许我们查看 Products
(产品)。
在 解决方案资源管理器中右键单击 Client
(客户端)节点,然后选择 添加屏幕。
使用 Products
(产品)表创建一个 通用屏幕集。
屏幕将被创建。
按 F5 运行应用程序。
注意:在调试时,您将自动以 TestUser
(测试用户)身份登录。
单击 添加 按钮来添加一个 Product
(产品)。
添加一个产品,然后单击 保存 按钮来保存它。
Product
(产品)将显示在一个列表中。
单击 Product
(产品)以在详细信息视图屏幕中显示它。
单击 编辑 按钮来编辑记录。
单击浏览器后退按钮返回上一页。
创建主页
现在我们将创建 主屏幕。
右键单击 Screens(屏幕)文件夹,然后选择 添加屏幕…
创建一个名为 Main(主)的新屏幕,使用 Orders
(订单)表作为 屏幕数据。
我们想做的第一件事是当用户单击列表中的 Order
(订单)时打开一个新屏幕。
单击 磁贴列表控件,然后在控件的属性中选择项目点击操作。
当 编辑项目点击操作对话框打开时,将屏幕连接到一个新的编辑屏幕。
选择 选择现有方法。
选择 Orders.editSelected
。
对于 导航至,选择 (新屏幕…),然后单击 确定。
将显示 添加新屏幕框。选择 订单明细 和 订单明细,然后单击 确定。
在 主页面上,我们需要添加一个按钮来创建新 Order
(订单)。
打开 主页面的 命令栏,然后单击添加按钮,创建到 AddEditOrder
(添加/编辑订单)页面的链接(处于添加模式)。
右键单击 主屏幕,然后选择 设置为首页,这样它将是我们运行应用程序时首先出现的屏幕。
查看到目前为止的应用程序…
运行应用程序。
我们看到可以使用下拉菜单导航到 产品页面。
当我们单击 添加订单按钮打开 添加/编辑订单对话框时,用户名并未为我们填写(也应该是只读的)。
订单日期也应设置为当前日期作为其默认值。
当我们切换到 订单明细选项卡时,我们没有添加 订单明细的按钮。
关闭网页浏览器,返回 Visual Studio。
创建订单明细编辑屏幕
为了允许我们创建和编辑 订单明细记录,打开 AddEditOrder
(添加/编辑订单)屏幕,在 订单明细(选项卡)下,选择 命令栏下的添加。
选择 OrderDetails
(订单明细)集合的 addAndEditNew
(添加并编辑新项)方法,以及 (新屏幕) 作为 导航至。
当 添加新屏幕对话框显示时,选择 订单明细详细信息作为 要包含的其他数据。
当 AddEditOrderDetail
(添加/编辑订单明细)屏幕打开时,右键单击包含 Order
(订单)下拉菜单的行布局,并删除它。
我们不需要显示 Order
(订单)(并允许其更改),因为它将在用户到达此屏幕时设置好。
我们将创建一个按钮来允许用户编辑 订单明细。
返回 AddEditOrder
(添加/编辑订单)屏幕。
单击 OrderDetails(订单明细) 磁贴列表,然后在属性中选择项目点击事件。
在 编辑项目点击操作对话框中,选择 OrderDetails.editSelected
(订单明细.编辑选中项)以及 导航至:添加/编辑订单明细(您在上一步创建的屏幕)。
当我们运行应用程序时,现在有了一个 添加订单明细的按钮。
我们可以单击 产品框中的带圆圈的加号图标来查看列表,以便选择一个 Product
(产品)。
然而,当我们创建 订单明细时,我们发现其显示可以改进。
关闭网页浏览器,返回 Visual Studio。
格式化订单明细
我们回到 添加/编辑订单屏幕,并将 订单明细磁贴列表控件更改为 列表
。
接下来,我们将 列表控件下的 行布局控件更改为 自定义控件。
在 自定义控件的属性中,我们选择 编辑渲染代码。
我们使用以下代码
myapp.AddEditOrder.rows_render = function (element, contentItem) { // We need to wait until the Products for the Order Detail are loaded // so we create a binding to "value.Product.ProductName" // When the data is loaded the binding will be raised // We will then have all the data required for our display contentItem.dataBind("value.Product.ProductName", function (newValue) { // clear the element element.innerHTML = ""; // Create a template var itemTemplate = $("<div><div>"); // Get the Product name and quantity var ProductName = contentItem.value.Product.ProductName; var ProductQuantity = ""; if (contentItem.value.Quantity !== undefined) { ProductQuantity = ' [' + contentItem.value.Quantity + ']'; } // Create the final display var FinalName = $("<h2>").text(ProductName + ProductQuantity); // Complete the template FinalName.appendTo($(itemTemplate)); itemTemplate.appendTo($(element)); }); };
(注意:此代码使用 Promises,有关 Promises 的更多信息,请参阅:在 Visual Studio LightSwitch 中使用 Promises。另请参阅:编写实现 Visual Studio LightSwitch 中绑定模式的 JavaScript)
当我们运行应用程序时,输出将按我们期望的方式格式化。
设置默认值
如果我们运行应用程序,然后单击 添加订单按钮…
…并尝试创建 订单,它将不会保存。
我们缺少 用户名。我们已经添加了代码来用当前用户覆盖 用户名,但由于我们将其设为必填字段,因此仍必须提供。我们可以仅将 用户名字段设为文本框并允许用户输入,但我们可以使用 ServerApplicationContext 来自动在客户端插入它。
请参阅以下文章以获取分步教程:在 LightSwitch HTML 客户端中检索当前用户
使用 Server Application Context
我们现在将创建一个文件处理程序,该处理程序将使用 Server Application Context API 来检索当前登录用户的 用户名。然后,我们将从客户端的 JavaScript 代码调用该处理程序,以填充屏幕上的值。
右键单击 Server(服务器)项目,然后选择 添加,然后选择 新建文件夹。
创建一个名为 Web 的文件夹。
右键单击 Web 文件夹,然后选择 添加,然后选择 新项。
创建一个名为 GetUserName.ashx 的新 通用处理程序。
(注意:您必须从头开始创建文件,以便将正确的引用添加到项目中。如果您仅仅复制粘贴或拖放文件到项目中,它将不起作用。)
为该文件使用以下代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace LightSwitchApplication.Web
{
public class GetUserName : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
using (var serverContext = ServerApplicationContext.CreateContext())
{
context.Response.ContentType = "text/plain";
context.Response.Write(serverContext.Application.User.Name);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
打开 Order
(订单)表,选择 HTML 客户端(选项卡),编写代码,然后选择 created
(创建)方法。
为该方法使用以下代码
myapp.Order.created = function (entity) {
// Set the default date for the Order
entity.OrderDate = new Date();
// Using a Promise object we can call the CallGetUserName function
msls.promiseOperation(CallGetUserName).then(function PromiseSuccess(PromiseResult) {
// Set the result of the CallGetUserName function to the
// UserName of the entity
entity.UserName = PromiseResult;
});
};
// This function will be wrapped in a Promise object
function CallGetUserName(operation) {
$.ajax({
type: 'post',
data: {},
url: '../web/GetUserName.ashx',
success: operation.code(function AjaxSuccess(AjaxResult) {
operation.complete(AjaxResult);
})
});
}
(注意:有关使用 msls.promiseOperation
的更多信息,请参阅 在 Visual Studio LightSwitch 中使用 Promises。)
最后,我们打开 AddEditOrder
(添加/编辑订单)屏幕,并将 用户名控件从 文本框更改为 文本
标签。
当我们运行应用程序时,用户名和日期现在在新记录创建时被设置。
您现在将能够创建和保存记录。
调用自定义查询
接下来,我们将调用之前创建的查询,以便显示当前用户的 Orders
(订单)数量。
打开 主屏幕,选择 添加数据项,并创建一个 整数
属性。
将该属性从 视图模型拖放到屏幕布局上。
在 属性中,将标签设为左对齐。
要设置该属性的值,请选择 编写代码,然后选择 created
(创建)方法。
使用以下代码
myapp.Main.created = function (screen) {
myapp.activeDataWorkspace.ApplicationData.OrdersForUser().execute().then
(function (results) {
var TotalCountOfOrders = CountOrders(results);
screen.TotalOrdersForCurrentUser = TotalCountOfOrders.toString();
});
};
function CountOrders(Orders) {
var TotalOrders = 0;
var orders = Orders.results;
orders.forEach(function (order) {
TotalOrders = TotalOrders + 1;
});
return TotalOrders;
}
当我们运行应用程序时,我们将看到 Orders
(订单)的计数。
调用自定义 JavaScript 查询
现在,我们希望在主页上显示 Order
(订单)时,显示关联的 订单明细的数量。
首先,我们打开 主页面,并删除 磁贴列表中的 用户名和创建者字段。
将 Id
(ID)字段添加到列表中。
将控件更改为 自定义控件。
为此控件的 Render
(渲染)方法使用以下代码
myapp.Main.Id_render = function (element, contentItem) {
// Get the current OrderId
var OrderId = contentItem.value;
var Int32 = ':Int32';
// Get all the OrderDetails associated with the current Order
var filter = '(Order/Id eq ' + msls._toODataString(OrderId, Int32) + ')';
msls.showProgress(myapp.activeDataWorkspace.ApplicationData.OrderDetails
.filter(filter)
.execute()
.then(function (result) {
// Loop through each record in the result
var index = 0;
var Entities = result.results;
Entities.forEach(function (entity) {
// Count the Order Details
index = index + 1;
})
// Set the final output
var NumberOfOrderDetails = $('<label class=msls-label-text>
Number of Order Details: ' + index + '</label>');
NumberOfOrderDetails.appendTo($(element));
}))
};
当我们运行应用程序时,我们将看到 Order
(订单)的 订单明细记录的数量。
但是,我们现在注意到,直到页面刷新后,主页面上的总计才显示正确的金额。我们可以自动刷新页面…
使用自定义按钮自动刷新页面
我们可以通过选择 主页面的 磁贴列表的 项目点击事件,然后选择 编写自己的方法来创建一个自定义按钮。
该方法将显示在屏幕设计器左侧的 视图模型中。
右键单击它,然后选择 编辑执行代码。
为该方法使用以下代码
myapp.Main.Orders_ItemTap_execute = function (screen) {
myapp.showAddEditOrder(null, {
beforeShown: function (addEditOrderScreen) {
// Set the Order on the AddEditOrder screen
// to the selected Order on the Main screen
addEditOrderScreen.Order = screen.Orders.selectedItem;
},
afterClosed: function (addEditScreen, navigationAction) {
// If the user commits the change,
// update the selected order on the Main screen
if (navigationAction === msls.NavigateBackAction.commit) {
// *****************************************
// Refresh the Orders
screen.Orders.load();
}
}
});
};
编辑记录后,总计会自动更新。
删除记录
打开 添加/编辑订单明细屏幕,并向 命令栏添加一个按钮。
为该按钮创建一个 删除方法。
右键单击 视图模型中的 Delete
(删除)方法,然后选择 编辑执行代码。
为该方法使用以下代码
myapp.AddEditOrderDetail.Delete_execute = function (screen) {
screen.OrderDetail.deleteEntity();
return myapp.commitChanges().then(null, function fail(e) {
myapp.cancelChanges();
throw e;
});
};
在编辑 订单明细时,删除按钮现在将显示。
您将需要单击 添加/编辑订单页面上的 保存按钮来提交更改。
我们还可以使用以下代码向 添加/编辑订单屏幕添加一个 删除按钮
myapp.AddEditOrder.Delete_execute = function (screen) {
screen.Order.deleteEntity();
myapp.commitChanges().then(null, function fail(e) {
msls.showMessageBox(e.message, {
title: "Error",
buttons: msls.MessageBoxButtons.ok
}).then(function (result) {
if (result === msls.MessageBoxResult.ok) {
// Discard Changes
screen.details.dataWorkspace.ApplicationData
.details.discardChanges();
}
});
});
};
您会注意到,如果我们尝试删除仍有 订单明细记录的 Order
(订单)…
…它将引发错误,因为我们之前在表之间创建的关系设置为不允许在存在关联记录的情况下删除 Order
(订单)。
请先删除所有 Order Details
(订单明细),然后您就可以删除 Order
(订单)。
LightSwitch 帮助网站文章
- LightSwitch HTML 客户端应用程序如何工作?
- 关于 LightSwitch HTML 客户端需要知道的 10 件事
- 完全控制 LightSwitch(ServerApplicationContext 和通用文件处理程序及 Ajax 调用)
- 在 Visual Studio LightSwitch HTML 客户端中保存数据(包括自动保存)
- 将 MVC 与 Visual Studio LightSwitch 结合使用
- 使用 ServerApplicationContext 创建 ASP.NET Web Forms CRUD 页面
- 在 Visual Studio LightSwitch 中使用 Promises
- 在 LightSwitch HTML 客户端中检索当前用户
- 编写实现 Visual Studio LightSwitch 中绑定模式的 JavaScript
LightSwitch 团队 HTML 和 JavaScript 文章
- LightSwitch HTML 客户端 API 概览(Elizabeth Maher)
- Visual Studio 2013 中的 LightSwitch 入门 - 地址簿 HTML 示例(Beth Massi)
- 与屏幕上的内容项交互(LightSwitch API)(Kevin Mehlhaff)
- 将 Twitter Feed 集成到 LightSwitch 应用程序中(Eric Erhardt)
- Office Developer Tools for Visual Studio 2013 – March 2014 Update
- LightSwitch 中的 Promises(Justin Anderson)
历史
- 2014 年 8 月 24 日:初始版本