从Dynamics CRM 2011 到Dynamics CRM 2013,变化最大的应该是UI了。它完全摒弃了传统的表单风格,而采用了前卫的Modern风格。所以Dynamics CRM 2013 的客户端框架发生了翻天复地的变化,本文将为大家来揭开他们的神秘面纱。
1. 客户端API的变化
Dynamics CRM 2013 为我们带来许多新的API,我认为比较重要的API分别是:context.getUserName, formSelector.items, entity.getPrimaryAttributeValue, data.refresh, data.Save, attribute.getIsPartyList, control.clearNotification, control.setNotification, ui.clearNotification, ui.setNotification, control.addCustomFilter, control.setShowTime, Utility.alertDialog, Utility.confirmDialog.
这些API中,有些是为了满足现有框架而推出的,比如:data.Save, utility.alertDialog, utility.confirmDialog。而有些则是对系统的增强:ui.setNotification, ui.clearNotification。推出新的API目的当然是方便广大的开发人员,并以此来获得更好的开发体验,并且能让开发人员对系统进行更新的控制。下面我们就按客户端架构来分别介绍一些新添加的API。
Context
新系统引进了新的Context机制,像onload,onsave,onchange这类支持事件管道的方法现在都支持管道的context了,并且这类事件也开始支持事件参数了。不同的时间处理器可以通过context进行协作。所以这块还是添加了不少新的API:
Context.getContext
Context.getDepth
Context.getEventArgs
Context.getEventSource
Context.get/setSharedVariable
//Application context var username=Xrm.Page.context.getUserName();
var clientState=Xrm.Page.context.client.getClientState();
var clientType=Xrm.Page.context.client.getClient();
var builder=new Sys.StringBuilder();
builder.appendLine("globe context");
builder.appendLine(String.format('username:{0}',username));
builder.appendLine(String.format('clientState:{0}',clientState));
builder.appendLine(String.format('clientType:{0}',clientType));
//Event context
var pipleContext=context.getContext();
var depth=context.getDepth();
var eventArgs=context.getEventArgs();
var eventSource=context.getEventSource();
context.setSharedVariable("jeff","Jeff Xiong");
builder.appendLine("event context");
builder.appendLine(String.format('depth:{0}',depth));
builder.appendLine(String.format('depth:{0}',context.getSharedVariable("jeff")));
// alertWindow(builder.toString());
FormSelector
新系统已经支持多form功能了,一个实体可以添加多个form,这些form和用户的安全角色关联来进行管理,也可以通过自定义代码来管理。所以这块的代码应该是个全新的东西。
formSelector.items
formSelector.items.get(0).getId
formSelector.items.get(0).getLabel
formSelector.items.get(0).navigate
function testFormSelector(){ var formSelector=Xrm.Page.ui.formSelector; var formNum=1; var builder=new Sys.StringBuilder(); formSelector.items.forEach(function(item, index){ builder.appendLine(String.format('form:{0}',++index)); builder.appendLine(String.format('form id:{0}',item.getId())); builder.appendLine(String.format('form label:{0}',item.getLabel())); }); alertWindow(builder.toString()); formSelector.items.get(1).navigate();}
Navigation
新系统的左侧导航栏已经移到顶部了,并且系统也为其增加了一些新的API:
Navigation.items.get(0).getId
Navigation.items.get(0).getLabel
Navigation.items.get(0).setFocus
Navigation.items.get(0).get/setVisible
function testNavigation(){ var navigation=Xrm.Page.ui.navigation; var formNum=1; var builder=new Sys.StringBuilder(); navigation.items.forEach(function(item, index){ builder.appendLine(String.format('form:{0}',++index)); builder.appendLine(String.format('form id:{0}',item.getId())); builder.appendLine(String.format('form label:{0}',item.getLabel())); }); alertWindow(builder.toString()); navigation.items.get(0).setFocus(true); navigation.items.get(1).setVisible(false);}
Data
新系统对Data对象进行了增强,不但扩展了已经存在的Save方法,而且也添加了新方法refresh。
Data.save().then(succCallBack,errorCallBack)
Data.refresh(bool:whether save record).then(succCallBack,errorCallBack)
Entity
新系统对entity对象做了些扩展,比如getDataXml方法以及对save方法的扩展。
entity.getDataXml
entity.getPrimaryAttributeValue
entity.save(null/saveandclose/saveandnew)
Attribute
针对lookup控件的addPreSearch方法还是比较有用,用他可以达到延迟执行的效果。这样我们就不用把所有过滤lookup控件视图的操作都放在onload函数里执行了。
attribute.getIsPartyList
attribute.addPreSearch
Notification
Notification在2011中被没有作为一个公开的API进行发布,但是新系统却将其进行发布了,并且我们的Notification还能控制到字段级别。我们现在可以选择的通知类型分别为:Form级别和Field级别。
function showNotification(){ var errorLevelId = '{D6F23104-E490-4A70-B326-93A5DCE4C3C5}'; var warningLevelId = '{C4F066E7-B7B7-4790-A848-F42812AC9109}'; var infoLevelId = '{BC05FE3E-8CDE-47D6-BF13-3BC28C9DB95B}'; var controlLevelId = '{B7F5B32C-71BD-4E5C-AA2D-DD0E861F752A}'; Xrm.Page.ui.setFormNotification('this is form notification', 'ERROR', errorLevelId); Xrm.Page.ui.setFormNotification('this is form notification', 'WARNING', warningLevelId); Xrm.Page.ui.setFormNotification('this is form notification', 'INFO', infoLevelId); Xrm.Page.getControl('new_string').setNotification('this is control notification', controlLevelId);}
UI
ui.close
ui.getCurrentControl
ui.refreshRibbon
ui.getViewPortHeight
ui.getViewPortWidth
Utility
utility.alertDialog
utility.confirmDialog
utility.openEntityForm
utility.openWebResource
2. UI布局的变化
Dynamics CRM 2011 和 Dynamics CRM 2013 最大的变化应该是在导航栏上,并且新系统还提供了组合字段:地址,以及方便自如的多表单切换功能和BPF,我相信之前的客户端编程知识已经不能满足我们了。下面我列一些个人觉得比较有挑战性的客户端自定义开发:
1. 自定义表单的弹出层,新系统用弹出层代替了旧系统的弹出页
2. JS控制BPF
3. 对组合字段的控制
4. 是否能对Partylist字段做更多的控制呢
5. 新系统的内容随机在contentIFrame0和contentIFrame1中显示,是否有一定的规律呢