关于Breeze.js+Angular.js+KendoUI+BootStrap+TypeScript+EF4.5的使用心得记录之一
提醒:博客开篇之作。望指导。不喜随便喷。
什么也不说,先上图。
就kendoui官网有详细的API说明,不做过多累赘,以下图中用到的控件为例:
一.DropDownList,Grid
页面简洁得体,是我个人比较偏爱的。主要来讲讲DropDownList和GridOnLineEdit结合Angular和BreezeJs的应用。
1.Breeze.js
☼功能:负责处理前端和后端程序的通讯。
用法:到官网下载Breeze包。在页面引入上图中JS。
添加Breeze.WebApi2.dll引用。 在后端控制器添加BreezeController特性。
[BreezeController(MaxAnyAllExpressionDepth = 2)] public class AppointmentsController : BaseController { readonly EFContextProvider<AppointmentContext> _contextProvider = new EFContextProvider<AppointmentContext>(); readonly EFContextProvider<LookupContext> _lookupContextProvider = new EFContextProvider<LookupContext>(); readonly EFContextProvider<SetupScreeningSiteContext> _siteContextProvider = new EFContextProvider<SetupScreeningSiteContext>(); readonly EFContextProvider<LookupScreeningParameterContext> _screenCentreContextProvider = new EFContextProvider<LookupScreeningParameterContext>(); TransactionSettings transactionSettings = null; /// <summary> /// Gets the context provider. /// </summary> /// <value> /// The context provider. /// </value> public EFContextProvider<AppointmentContext> ContextProvider { get { return _contextProvider; } } /// <summary> /// Gets or sets the transaction settings. /// </summary> /// <value> /// The transaction settings. /// </value> public TransactionSettings TransactionSettings { get { return transactionSettings; } set { transactionSettings = value; } } /// <summary> /// Returns metadata string serialized from data context. /// </summary> /// <returns>string</returns> [AccessRightAuthorize(AccessRight.DEFAULT_SITE)] //[AccessRightAuthorize(AccessRight.APPOINT_READ)] [HttpGet] public string Metadata() { string metadata = string.Empty; try { metadata = _contextProvider.Metadata(); return ControllerHelper.attachDisplayNameToMetadata(metadata); } catch (Exception ex) { if (this.HandleException(ex)) { throw ex; } } return metadata; }
public getScreeningCentreById(centreId: number, forceRemote: boolean): breeze.promises.IPromise<App.DataAccess.Setups.ScreeningParameterModel.IEntityCentre> { var query = this.entityQuery .from("GetScreeningCentreParametersById") .withParameters({ centreId: centreId }); return this.manager.executeQuery(query) .then((data) => { return data.results[0]; }); }
breaze.js的语法类似LINQ。
列举简单例子:
this.entityQuery.from("数据集合/后台方法名").withParameters("参数1,参数2,······").
where("查询条件").orderByDesc("排序属性").inlineCount();
this.manager.executeQueryLocally(query)
this.manager.executeQuery(query)
是不是非常眼熟。当执行这段代码的时候。才会去数据拿数据。manager是breeze在JS中定义的Entity。类似EF的概念。
executeQueryLocally是查询在缓存中的数据。默认只要查过的数据都会存在manager缓存中。executeQuery不会取缓
存数据。每次都会去执行后台代码,从数据库拿。
工作原理:
当用户发起数据请求,系统会自动去找到改页面对应的控制器。通过Metadata()方法,拿到所需要的所有数据结构并且
返回给前端。
(注意:如果第一次是更新操作,没有拿数据结构,则必须先执行查询操作,否则会报错。)
页面所有操作的数据会缓存浏览器然后通过SaveChanges方法更新到数据库。参数"JObject saveBundle” 是JSON对象
。之前通过Metadata()拿到的所有结构和数据都会在里面。(优点:减少代码量,缺点:性能是个question.),当然,你也
可以选择存储过程。至于Breeze.WebApi2.dll 的内部实现,这节我们后面的章节会详细说明。
通过这一系列的准备工作。就可以进行数据交互了。
2.数据展示。Grid
拿到数据之后绑定到Kendo Ui就是几个参数配置的事情。但是,由于使用了Breeze,拿到的数据时beeze Entity的数据结构
形式的JSON,不被KendoUI Grid的schema所认识,我得和你搞好关系,你才能帮我办事。怎么办,重写Schema,先变成
你认识的样子再说。于是就有了下面这段:
//#region Breeze kendo grid extention Methods public createSchema = (resourceName: string): any => { var schema: App.Shared.IBreezeKendoGridSchema = { total: function (data) { return data.total; }, model: {} }; try { var typeObj = this.service.domainManager.getTypeByResourceName(resourceName); } catch (ex) { return schema; } var model: App.Shared.IBreezeKendoGridModel = { fields: {}, id: {} }; if (typeObj.keyProperties) { if (typeObj.keyProperties.length == 1) { model.id = typeObj.keyProperties[0].name; } else if (typeObj.keyProperties.length > 1) { var msg = "Multiple-key ID not supported"; this.logError(msg, "createSchema"); //typeObj.keyProperties.forEach(function (keyProp) { // model.id[keyProp.name] = keyProp.name; //}); } } typeObj.dataProperties.forEach(function (prop) { var type = "string"; if (prop.dataType.isNumeric) { type = "number"; } else if (prop.dataType.isDate) { type = "date"; } else if (prop.dataType.getName() == "Boolean") { type = "boolean"; } model.fields[prop.name] = { type: type, defaultValue: prop.defaultValue, nullable: prop.isNullable }; }); schema.model = model; return schema; } //#endregion
做完整容之后,按照Kendo UI官网配置来,就有了下面的图片。
备注:个人认为这套架构最大的优点就是无需业务层的任何数据操作代码。大大的减少代码量。提高了开发效率。与此同时,由于
数据操作代码和展示层都是TypeScript实现。几乎全站所有的代码,可以轻而易举的Copy。辛辛苦苦多少个日夜,一建
Copy全带走。