版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
./動態(tài)擴(kuò)展平臺擴(kuò)展腳本編寫指南EAS產(chǎn)品部技術(shù)架構(gòu)部賀召軍導(dǎo)讀闡述基于動態(tài)擴(kuò)展平臺DEP開發(fā)的擴(kuò)展腳本編寫指南和相關(guān)注意事項,通過本規(guī)范指導(dǎo)開發(fā)工作。適用讀者實施人員、現(xiàn)場二次開發(fā)人員、研發(fā)中心客戶化開發(fā)人員。適用范圍金蝶EASV7.0SP1。.簡介3指定作用域3變量4函數(shù)4使用擴(kuò)展腳本5第一章上下文51.1插件上下文〔pluginCtx5獲取服務(wù)端上下文6獲取客戶端上下文7獲取界面控件71.2方法上下文〔methodCtx8獲取方法參數(shù)8獲取方法返回值8設(shè)置方法返回值8方法上下文常用方法81.3快速插入上下文腳本9第二章調(diào)用業(yè)務(wù)方法92.1調(diào)用方式10客戶端調(diào)用業(yè)務(wù)方法方式11服務(wù)器端調(diào)用業(yè)務(wù)方法方式132.2快速插入業(yè)務(wù)方法調(diào)用13第三章自定義異常143.1定義自定義異常143.2腳本中調(diào)用自定義異常14服務(wù)器端調(diào)用異常方式14客戶端異常調(diào)用方式153.3快速插入自定義異常調(diào)用15第四章自定義基礎(chǔ)資料或單據(jù)164.1獲取自定義基礎(chǔ)資料和單據(jù)遠(yuǎn)程接口164.2傳入?yún)?shù)174.3返回值類型184.4示例腳本19第五章給常用控件添加事件205.1F7205.2CheckBox215.3ComboBox215.4Button215.5TextFiled215.6Tree235.7TabledPane235.8Table23第六章使用函數(shù)庫246.1定義函數(shù)庫246.2使用函數(shù)庫26第七章打點提示——快速編寫腳本277.1環(huán)境準(zhǔn)備277.2使用打點提示29第八章調(diào)試腳本298.1調(diào)試準(zhǔn)備298.1.1客戶端調(diào)試29服務(wù)器端調(diào)試308.2進(jìn)行調(diào)試318.2.1變量查看328.2.2使用腳本控制臺328.3監(jiān)聽事件方法內(nèi)部調(diào)試338.4調(diào)試完成33第九章常見問題349.1在腳本里添加里添加了監(jiān)聽器,在代碼里刪除監(jiān)聽器的時候的報中斷錯誤349.2擴(kuò)展腳本不能調(diào)用當(dāng)前類的private方法,不能用super來調(diào)用父類方法359.3擴(kuò)展腳本中不能使用強(qiáng)制類型轉(zhuǎn)換35附錄一關(guān)于Rhino37Rhino語法簡介37歷史簡介37JavaScript中的"Java"38Rhino和java語言的具體區(qū)別39數(shù)組39聯(lián)合數(shù)組39通過屬性進(jìn)行循環(huán)40正則表達(dá)式40函數(shù)顯式聲明41添加方法42添加更多的方法42使用原型43無類編碼43基于類的語言與基于原型的語言的比較44附錄二案例腳本45簡介擴(kuò)展腳本運行引擎為Rhino,基于javascript語法,運行期解釋執(zhí)行。jvm中的類的方法和屬性均可應(yīng)用于腳本中,調(diào)用方式類似于代碼調(diào)試。比如下面一段腳本://客戶端設(shè)置編碼規(guī)則腳本//定義引入變量vareasNames=JavaImporter<>;//引入指定包dingrule>;//使用引入作用域with<easNames>{//從上下文中獲取編輯界面編輯對象vareditData=pluginCtx.getDataObject<>;//取得f7控件varbizOrgUnit=pluginCtx.getKDBizPromptBox<"prmtSaleOrgUnit">.getValue<>;//遠(yuǎn)程方法調(diào)用獲取編碼varnumber=CodingRuleManagerFactory.getRemoteInstance<>.getNumber<editData,bizOrgUnit.getId<>>;//設(shè)置TextField編碼pluginCtx.getKDTextField<"txtNumber">.setText<number>;}指定作用域在示例代碼中vareasNames=JavaImporter<>;easNames.importPackage<Packages.>;和java中import類似,這里使用JavaImporter<>的importPackage引入包,CodingRuleManagerFactory屬于該包中的內(nèi)容,但其處在with<easNames>{…}中,所以不需要指定其全路徑,即可調(diào)用getRemoteInstance<>方法,如果需要引入其它包,則增加easNames.importPackage<Packages.包路徑>;即可。如果沒使用with指定作用域,則必須使用全名稱〔包名+類名。注意:當(dāng)引入的不同包路徑下有重復(fù)的類名稱情況下,在with<easNames>{作用域中,該類名在引用時也需要指定其全路徑。變量使用var聲明變量,聲明時無具體類型運行期確定類型。例如vareditData=pluginCtx.getDataObject<>;聲明editData為編輯界面的編輯對象。變量的定義聲明遵循javascript語法。函數(shù)使用function關(guān)鍵字開始函數(shù)的聲明,在函數(shù)聲明中看不到類型,包含參數(shù)和返回值,如下所示//創(chuàng)建值對象functioncreateNewData<entityBosType,entityPK>{varobjectValue=newcom.kingdee.eas.ep.DataBaseCustomInfo<>;objectValue.setBOSType<entityBosType>;objectValue.setPK<newcom.kingdee.bos.metadata.MetaDataPK<entityPK>>;returnobjectValue;}然后就可以調(diào)用了定義的函數(shù)了varbizInterface=com.kingdee.bos.BOSObjectFactory.createRemoteCommonBOSObject<newcom.kingdee.bos.metadata.MetaDataPK<entityPK>>;bizInterface.addnew<createNewData<entityBosType,entityPK>>;//新增在javaScript中沒有類的概念,接口實現(xiàn)也使用關(guān)鍵字function聲明。比如給一些控件增加監(jiān)聽器://F7控件增加值改變監(jiān)聽pluginCtx.getKDBizPromptBox<"prmtHROrg">.addDataChangeListener<function<event>{com.kingdee.eas.util.client.MsgBox.showInfo<"DATACHANGED:"+event.getOldValue<>+"$$$$"+event.getNewValue<>>;}>;//KDTable增加表格編輯事件監(jiān)聽pluginCtx.getKDTable<"kdtEntrys">.addKDTEditListener<function<event,methodName>{if<methodName=="editStopped">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$EditStopped">;}}>;使用擴(kuò)展腳本擴(kuò)展定義:針對擴(kuò)展點編寫擴(kuò)展腳本。擴(kuò)展點:能夠支持?jǐn)U展腳本的公用業(yè)務(wù)方法,需要改變其執(zhí)行效果預(yù)期的地方。在實體或ui里擴(kuò)展定義可編寫擴(kuò)展腳本,選擇某個葉子節(jié)點即可編寫針對該業(yè)務(wù)方法的前置腳本和后置腳本。前置腳本在業(yè)務(wù)方法被調(diào)用前被執(zhí)行,后置腳本在業(yè)務(wù)方法返回后被執(zhí)行。腳本中可以使用業(yè)務(wù)方法的參數(shù),也可以設(shè)置業(yè)務(wù)方法的返回值。第一章上下文擴(kuò)展腳本中封裝了兩種上下文,插件上下文〔pluginCtx和方法上下文〔methodCtx。這兩種上下文為系統(tǒng)內(nèi)置,無需額外的聲明或獲取。pluginCtx主要存放當(dāng)前執(zhí)行環(huán)境的相關(guān)信息,比如服務(wù)端的Context,客戶端的界面控件、界面狀態(tài)、編輯對象等。methodCtx存放當(dāng)前操作的相關(guān)信息,包含方法參數(shù)和方法返回值。1.1插件上下文〔pluginCtx客戶端和服務(wù)端的插件上下文存儲的內(nèi)容不一樣,實現(xiàn)方式上,其分別對應(yīng)于兩個java類,和。這兩個類中的方法均可以在腳本中直接使用。上下文都存在get和put方法。腳本中直接使用get<key>獲取值,put<key,value>設(shè)置值。獲取服務(wù)端上下文服務(wù)端通過pluginCtx.getContext<>獲取服務(wù)端上下文,比如://服務(wù)端更新單據(jù)狀態(tài)varimp=JavaImporter<>;imp.importPackage<P.kingdee.eas.util.app>;with<imp>{//獲取服務(wù)端上下文varctx=pluginCtx.getContext<>;//獲取方法參數(shù)varbillId=methodCtx.getParamValue<0>;varsql="updateT_SD_SALEORDERSETFBASESTATUS="+status+"WHEREFID='"+billId+"'";//執(zhí)行sql,使用服務(wù)器端上下文DbUtil.execute<ctx,sql>;}服務(wù)器端上下文常見用法描述服務(wù)器端上下文用法獲取當(dāng)前用戶com.kingdee.eas.util.app.ContextUtil.getCurrentUserInfo<pluginCtx.getContext<>>;獲取client端IPl.getClientIP<pluginCtx.getContext<>>;獲取client端名稱com.kingdee.eas.util.app.ContextUtil.getClientName<pluginCtx.getContext<>>;獲取當(dāng)前CUcom.kingdee.eas.util.app.ContextUtil.getCurrentCtrlUnit<pluginCtx.getContext<>>;獲取當(dāng)前財務(wù)組織〔公司com.kingdee.eas.util.app.ContextUtil.getCurrentFIUnit<pluginCtx.getContext<>>;獲取當(dāng)前行政組織com.kingdee.eas.util.app.ContextUtil.getCurrentAdminUnit<pluginCtx.getContext<>>;獲取當(dāng)前HR組織com.kingdee.eas.util.app.ContextUtil.getCurrentHRUnit<pluginCtx.getContext<>>;獲取當(dāng)前數(shù)據(jù)庫類型com.kingdee.eas.util.app.ContextUtil.getDbType<pluginCtx.getContext<>>;獲取當(dāng)前組織單元com.kingdee.eas.util.app.ContextUtil.getCurrentOrgUnit<pluginCtx.getContext<>>;獲取客戶端上下文客戶端插件上下文封裝了部分常用的內(nèi)容,具體如下:描述獲取客戶端上下文獲取界面上下文java.util.MapgetUIContext<>獲取組織上下文com.kingdee.bos.ContextgetMainOrgContext<>獲取界面狀態(tài),比如新增、編輯java.lang.StringgetOprtState<>獲取當(dāng)前編輯對象,編輯界面的editDatacom.kingdee.bos.dao.IObjectValuegetDataObject<>獲取界面綁定.DataBindergetDataBinder<>獲取規(guī)則處理com.kingdee.eas.framework.client.UILifeCycleHandergetLifeCycleHander<>獲取當(dāng)前界面實例com.kingdee.bos.ui.face.IUIObjectgetUI<>獲取組織pluginCtx.getUIContext<>.get<"sysContext">.getCurrentFIUnit<>獲取界面狀態(tài)pluginCtx.getUI<>.getOprtState<>;獲取界面ActionpluginCtx.getUI<>.getActionManager<>.getAction<"actionName">直接通過pluginCtx調(diào)用即可,比如pluginCtx.getUI即可獲取當(dāng)前界面實例。獲取界面控件界面的控件可以通過get+控件類型+<+控件名+>的方式獲得,比如獲取單據(jù)分錄的表格可以這樣pluginCtx.getKDTable<"kdtEntries">??丶纠齠7控件pluginCtx.getKDBizPromptBox<"name">;容器控件pluginCtx.getKDContainer<"name">;textField控件pluginCtx.getKDTextField<"name">;KDTextArea控件pluginCtx.getKDTextArea<"name">;KDPasswordField控件pluginCtx.getKDPasswordField<"name">;KDFormattedTextField控件pluginCtx.getKDFormattedTextField<"name">;KDDateTimeField控件pluginCtx.getKDDateTimeField<"name">;KDCheckBox控件pluginCtx.getKDCheckBox<"name">;KDRadioButton控件pluginCtx.getKDRadioButton<"name">;KDMenu控件pluginCtx.getKDMenu<"name">;KDMenuItem控件pluginCtx.getKDMenuItem<"name">;KDTree控件pluginCtx.getKDTree<"name">;KDTreeView控件pluginCtx.getKDTreeView<"name">;KDList控件pluginCtx.getKDList<"name">;KDTimePicker控件pluginCtx.getKDTimePicker<"name">;KDDatePicker控件pluginCtx.getKDDatePicker<"name">;KDTabbedPane控件pluginCtx.getKDTabbedPane<"name">;1.2方法上下文〔methodCtx方法上下文存放了方法的相關(guān)信息,包括方法參數(shù)和方法返回值。方法上下文提供如下我們來看這個示例,刪除主表記錄時也刪除對應(yīng)表的紀(jì)錄//服務(wù)端更新單據(jù)狀態(tài)varimp=JavaImporter<>;imp.importPackage<P.kingdee.eas.util.app>;with<imp>{varctx=pluginCtx.getContext<>;varbillId=methodCtx.getParamValue<0>;//獲取參數(shù)varisDone=methodCtx.getResultValue<>;//獲取方法返回值是否成功執(zhí)行varstatus=11;varsql="deleteT_SD_SALEORDERWHEREFBillID='"+billId+"'";if<isDone>{DbUtil.execute<ctx,sql>;}methodCtx.setResultValue<java.lang.Boolean.TRUE>;//設(shè)置方法返回值}1.2.1獲取方法參數(shù)如果想獲得方法的某個參數(shù),比如delete<Stringpk>的參數(shù),這可以通過methodCtx.getParamValue<0>來獲得單據(jù)的pk。示例中以varbillId=methodCtx.getParamValue<0>;來獲取參數(shù)需要刪除單據(jù)的id1.2.2獲取方法返回值描述:可以通過methodCtx.getResultValue<>來獲得方法的返回值。用法:一般在后置腳本中使用,如示例代碼中,通過狀態(tài)方法是否成功執(zhí)行來判斷是否需要刪除對于表的紀(jì)錄:varisDone=methodCtx.getResultValue<>;1.2.3設(shè)置方法返回值設(shè)置方法的返回值必須通過methodCtx.setResultValue<value>來設(shè)置,不可以用類似方法返回值的方式寫〔returnvalue。如示例代碼中設(shè)置方法返回值為TRUE。lean.TRUE>方法上下文常用方法描述方法獲取方法名StringgetName<>獲取方法別名StringgetAlias<>獲取方法參數(shù)類型String[]getParamTypes<>獲取方法某個參數(shù)的類型StringgetParamType<intindex>獲取方法參數(shù)值Object[]getParamValues<>獲取方法某個參數(shù)值ObjectgetParamValue<intindex>獲取方法返回值類型StringgetResultType<>獲取方法返回值ObjectgetResultValue<>設(shè)置方法返回值voidsetResultValue<Objectvalue>1.3快速插入上下文腳本可以通過動態(tài)擴(kuò)展平臺的擴(kuò)展定義中的上下文來快速編寫一些常用腳本。雙擊這里自動生成模板腳本雙擊這里自動生成模板腳本如上圖所示,當(dāng)選擇擴(kuò)展點后,切換到上下文頁簽,選中前置或后置腳本,雙擊所需樹結(jié)點,就可以自動生成模版腳本,例如雙擊當(dāng)前用戶生成模板腳本:extUtil.getCurrentUserInfo<pluginCtx.getContext<>>;第二章調(diào)用業(yè)務(wù)方法在實體或Fa?ade中新增一個業(yè)務(wù)方法后,如何調(diào)用該業(yè)務(wù)方法?自定義業(yè)務(wù)方法的調(diào)用是通過工具類來實現(xiàn)的,該實現(xiàn)方式同樣適用標(biāo)準(zhǔn)產(chǎn)品中已有的業(yè)務(wù)方法調(diào)用,下面將說明。2.1調(diào)用方式 調(diào)用自定義業(yè)務(wù)方法和標(biāo)準(zhǔn)產(chǎn)品已有的業(yè)務(wù)方法方式相同,下面我們在實體上新增一個自定義一個業(yè)務(wù)方法helloWord。返回值類型方法名參數(shù)返回值類型方法名參數(shù) 然后可到擴(kuò)展定義中找到該新增方法的方法描述??截惪色@取方法描述拷貝可獲取方法描述2.1.1客戶端調(diào)用業(yè)務(wù)方法方式com.kingdee.bos.framework.BOClientTool.callCmethod<pk,methodSignature,args>元數(shù)據(jù)PK〔IMetaDataPKpk方法名稱〔StringmethodSignature參數(shù)對象數(shù)組〔Object[]args復(fù)制這里獲取元數(shù)據(jù)全路徑其中元數(shù)據(jù)PK為實體的全名稱,可從元數(shù)據(jù)檢查獲得:復(fù)制這里獲取元數(shù)據(jù)全路徑方法名稱請從該業(yè)務(wù)方法的擴(kuò)展點的描述信息中拷貝獲得,否則容易出錯,如果方法沒有返回值,注意名稱前有空格,不要刪除。比如://客戶端調(diào)用服務(wù)端方法vareasNames=JavaImporter<>;easNames.importPackage<P.kingdee.bos.ctrl.extendcontrols>;easNames.importPackage<P.kingdee.bos.util>;easNames.importPackage<P.kingdee.bos.metadata>;easNames.importPackage<P.kingdee.bos.framework>;with<easNames>{//定義所需參數(shù)//元數(shù)據(jù)pkvarpk=newMetaDataPK<"">;//方法名稱請從該業(yè)務(wù)方法的擴(kuò)展點的描述信息中拷貝獲得,否則容易出錯,如果方法//沒有返回值,注意名稱前有空格,不要刪除varname="java.lang.BooleanupdateStatus<com.kingdee.bos.util.BOSUuidbillId>";//參數(shù),以數(shù)組形式保存,js數(shù)組定義格式請參見HYPERLINK附錄.數(shù)組//下面示例中為一個參數(shù)BOSUuidvarparams=[BOSUuid.read<"2s5eatuISSqb7TuLMfibSMSKQjo=">];業(yè)務(wù)方法描述中拷貝過來據(jù)全路徑業(yè)務(wù)方法描述中拷貝過來據(jù)全路徑varresult=BOClientTool.callCmethod<pk,name,params>;MsgBox.showInfo<"Resultis:"+result>;com.kingdee.eas.util.SysUtil.abort<>;}2.1.2服務(wù)器端調(diào)用業(yè)務(wù)方法方式com.kingdee.bos.framework.BOProxy.getProxy<pluginCtx.getContext<>,pk>.callCmethod<methodSignature,args>服務(wù)端上下文〔Contextctx元數(shù)據(jù)PK〔IMetaDataPKpk方法名稱〔StringmethodSignature參數(shù)對象數(shù)組〔Object[]args參數(shù)獲取方式參見客戶端業(yè)務(wù)方法調(diào)用。2.2快速插入業(yè)務(wù)方法調(diào)用自動生成模板腳本據(jù)全路徑雙擊這里可以通過動態(tài)擴(kuò)展平臺的擴(kuò)展定義中的上下文頁簽中"調(diào)用自定義業(yè)務(wù)方法節(jié)點"快速生成調(diào)用業(yè)務(wù)方法模版腳本,如下圖所示:自動生成模板腳本據(jù)全路徑雙擊這里com.kingdee.bos.framework.BOProxy.getProxy<pluginCtx.getContext<>,pk>.callCmethod<methodSignature,args>然后替換相應(yīng)參數(shù)即可。小提示:使用快速插入業(yè)務(wù)方法調(diào)用方式,你不需要關(guān)心使用客戶端方式還是服務(wù)端方式,平臺會自動根據(jù)當(dāng)前方法判斷調(diào)用方式第三章自定義異常3.1定義自定義異常建立一個方案后,會自動創(chuàng)建一個異常,增加異常只需增加子異常即可。業(yè)務(wù)異常定義后,可以通過工具類拋出異常。在一個異常中子異常號不能重復(fù)。3.2腳本中調(diào)用自定義異常在腳本中使用工具類調(diào)用自定義異常,該類中將根據(jù)異常名和子異常名獲取異常并拋出.服務(wù)器端調(diào)用異常方式服務(wù)器端調(diào)用方式:s.ep.plugin.ExceptionUtil.throwOnServer<pluginCtx.getContext<>,name,subName,args>其中參數(shù)為:Contextctx-服務(wù)器上下文Stringname-異常名稱StringsubName-子異常名稱Object[]args-參數(shù)對象數(shù)組,可刪去args[i]中的內(nèi)容將會替代對應(yīng)的{i}中的內(nèi)容,如果沒有參數(shù),可以省略該參數(shù)。客戶端異常調(diào)用方式客戶端調(diào)用方式:com.kingdee.eas.ep.plugin.ExceptionUtil.throwOnClient<name,subName,args>參數(shù)含義Stringname-異常名稱StringsubName-子異常名稱Object[]args-參數(shù)對象數(shù)組,可刪去args[i]中的內(nèi)容將會替代對應(yīng)的{i}中的內(nèi)容,如果沒有參數(shù),可以省略該參數(shù)。3.3快速插入自定義異常調(diào)用雙擊據(jù)全路徑自動生成模板腳本據(jù)全路徑可以通過動態(tài)擴(kuò)展平臺的擴(kuò)展定義中的上下文頁簽中"異常工具"快速生成調(diào)用異常雙擊據(jù)全路徑自動生成模板腳本據(jù)全路徑雙擊自動生成com.kingdee.eas.ep.plugin.ExceptionUtil.throwOnClient<name,subName,args>,然后替換相應(yīng)參數(shù)即可。已3.1中新建異常為例,則替換為:com.kingdee.eas.ep.plugin.ExceptionUtil.throwOnClient<"TesttException","ssssd",["參數(shù)1","參數(shù)2"]>;運行效果如下圖所示。注意一:異常信息中可以存在"{數(shù)字}"這種格式的內(nèi)容,表示這部分需要在運行時替換為具體信息。比如異常定義為"測試異常;參數(shù)一:{0},參數(shù)二{1}",調(diào)用該異常的時候,以數(shù)組形式傳入?yún)?shù):["參數(shù)1","參數(shù)2"]第四章自定義基礎(chǔ)資料或單據(jù)動態(tài)擴(kuò)展平臺支持自定義基礎(chǔ)資料和單據(jù)的實現(xiàn)原理是先通過內(nèi)置的模板拷貝生成新的動態(tài)元數(shù)據(jù),然后通過模板這個殼來運行。新生成的元數(shù)據(jù)可進(jìn)行業(yè)務(wù)調(diào)整。所有對動態(tài)內(nèi)容的操作,最終都轉(zhuǎn)換為對模板的操作,模板根據(jù)具體元數(shù)據(jù)的信息,進(jìn)行相應(yīng)的轉(zhuǎn)換后,再執(zhí)行操作。4.1獲取自定義基礎(chǔ)資料和單據(jù)遠(yuǎn)程接口首先新建自定義基礎(chǔ)資料或單據(jù),從模板復(fù)制,選擇包名,輸入名稱,如:路徑:com.king名稱:Termsofapply選擇模板據(jù)全路徑輸入實體名稱據(jù)全路徑選擇模板據(jù)全路徑輸入實體名稱據(jù)全路徑選擇新建基礎(chǔ)資料或單據(jù)路徑據(jù)全路徑創(chuàng)建完成后,客戶端調(diào)用新增、修改、查詢等動作首先需要一個遠(yuǎn)程接口,可通過如下方式獲得:varbizInterface=com.kingdee.bos.BOSObjectFactory.createRemoteCommonBOSObject<newcom.kingdee.bos.metadata.MetaDataPK<entityPK>>其中entityPK為自定義基礎(chǔ)資料的路徑+".app."+包名<實體的全名稱>,如示例中則為:.app.Termsofapply4.2傳入?yún)?shù)獲取遠(yuǎn)程接口需要傳入entityPK,為自定義基礎(chǔ)資料的實體的全名稱,如""。其也可在自定義基礎(chǔ)資料實體元數(shù)據(jù)檢查中獲得,如下圖打開元數(shù)據(jù)檢查元數(shù)據(jù)檢查據(jù)全路徑元數(shù)據(jù)檢查據(jù)全路徑取其中entityObject屬性獲取實體全名。復(fù)制獲取實體全路徑據(jù)全路徑復(fù)制獲取實體全路徑據(jù)全路徑4.3返回值類型返回值為com.kingdee.eas.ep.IDataBaseCustom類型,這是由于其從該模板生成所致。這樣IDataBaseCustom上的所有操作,動態(tài)基礎(chǔ)資料都有,也均可以通過該實例執(zhí)行。4.4示例腳本以新增操作為例,新增如下,首先獲取entityPK〔HYPERLINK參見4.2.,元數(shù)據(jù)查獲取BOSType,如下圖:復(fù)制獲取實體bosType據(jù)全路徑復(fù)制獲取實體bosType據(jù)全路徑//創(chuàng)建值對象functioncreateNewData<entityPK>{varobjectValue=newcom.kingdee.eas.ep.DataBaseCustomInfo<>;varentityBosType="9DD486DB";//實體的bosType,可通過[元數(shù)據(jù)檢查]獲得objectValue.setBOSType<newcom.kingdee.bos.util.BOSObjectType<entityBosType>>;//實體的PK,可通過[元數(shù)據(jù)檢查]獲得ta.MetaDataPK<entityPK>>;returnobjectValue;}varentityPK="com.kingdee.eas.basedata.assistant.app.Termsofapply";varobject=createNewData<entityPK>;//通過實體PK獲取自定義基礎(chǔ)資料或單據(jù)接口,所需參數(shù)為實體pkvarbizInterface=com.kingdee.bos.BOSObjectFactory.createRemoteCommonBOSObject<newcom.kingdee.bos.metadata.MetaDataPK<entityPK>>;bizInterface.addnew<object>;//新增<<com.kingdee.eas.ep.DataBaseCustomInfo>object>.setName<"TestName">;object.setId<opk.getKeyValue<"id">>;object.setName<"myName">;bizInterface.update<opk,object>;//更新//更新值對象//需要更新記錄的id,實際調(diào)用過程可從參數(shù)等取得varfid="87aUzEo7QWiREPo/LfoyDp3Uhts="varentityPK="com.kingdee.eas.basedata.assistant.app.Termsofapply";//通過實體PK獲取自定義基礎(chǔ)資料或單據(jù)接口,所需參數(shù)為實體pkvarbizInterface=com.kingdee.bos.BOSObjectFactory.createRemoteCommonBOSObject<newcom.kingdee.bos.metadata.MetaDataPK<entityPK>>;//通過id〔字符串型創(chuàng)建ObjectUuidPK為更新方法所須參數(shù)類型varopk=newcom.kingdee.bos.dao.ormapping.ObjectUuidPK<com.kingdee.bos.util.BOSUuid.read<fid>>;//取得原值對象varobject=bizInterface.getValue<opk>;//更改值對象某些屬性object.setName<"myTestUpdateName">;//更新bizInterface.update<opk,object>;//刪除值對象varfid="87aUzEo7QWiREPo/LfoyDp3Uhts="http://需要更新記錄的idvarentityPK="com.kingdee.eas.basedata.assistant.app.Termsofapply";varbizInterface=com.kingdee.bos.BOSObjectFactory.createRemoteCommonBOSObject<newcom.kingdee.bos.metadata.MetaDataPK<entityPK>>;varopk=newcom.kingdee.bos.dao.ormapping.ObjectUuidPK<com.kingdee.bos.util.BOSUuid.read<fid>>;bizInterface.deleteBatchData<[opk]>;//刪除注意:值對象創(chuàng)建必須設(shè)置一個實體的bosType和PK,引擎是通過這兩項進(jìn)行ORMMapping的。刪除、更新、查看等動作由于值對象都存在id,所以其可以自動解析獲得,不需要手工設(shè)置bosType和PK。對于刪除操作,需要用deleteBatchData,參數(shù)為ObjectUuidPK數(shù)組。第五章給常用控件添加事件5.1F7給F7添加DataChange事件//F7控件增加值改變監(jiān)聽pluginCtx.getKDBizPromptBox<"prmtHROrg">.addDataChangeListener<function<event>{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$PromptBox">;//dosomething}>;5.2CheckBoxwith<easNames>{varchkIsCentralBalance=pluginCtx.getKDCheckBox<"chkIsCentralBalance">;chkIsCentralBalance.addChangeListener<function<event>{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$CheckBox">;//dosomething}>;}5.3ComboBox//選擇事件with<easNames>{vardataSourceCombo=pluginCtx.getKDComboBox<"dataSourceCombo">;dataSourceCombo.addItemListener<function<event,method>{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$ComboBox">;//dosomething}>;}5.4Button//Button點擊事件varokkDButton=pluginCtx.getKDButton<"okkDButton">;okkDButton.addActionListener<function<event>{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$Button">;//dosomething}>;5.5TextFiledvarmyTextFiled=pluginCtx.getKDTextFiled<"myTextFiled">;myTextFiled.addActionListener<function<event>{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$myTextFiled">;//dosomething}>;//添加焦點事件myTextFiled.addFocusListener<function<event,methodName>{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$myTextFiledFocusListener">;if<methodName=="focusGained">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$focusGained">;//dosomething}if<methodName=="focusLost">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$focusLost">;//dosomething}//dosomething}>;//添加鼠標(biāo)事件myTextFiled.addMouseListener<function<event,methodName>{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$myTextFiledMouseListener">;if<methodName=="mouseClicked">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$mouseClicked">;//dosomething}if<methodName=="mousePressed">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$mousePressed">;//dosomething}if<methodName=="mouseReleased">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$mouseReleased">;//dosomething}if<methodName=="mouseEntered">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$mouseEntered">;//dosomething}if<methodName=="mouseExited">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$mouseExited">;//dosomething}}>;5.6Tree//增加tree的選擇事件varaccountTree=pluginCtx.getKDTree<"accountTree">;accountTree.addTreeSelectionListener<function<event>{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$KDTree">;//dosomething}>;5.7TabledPanevarmyTabbedPane=pluginCtx.getTabbedPane<"myTabbedPane">;//頁簽切換事件myTabbedPane.addChangeListener<function<event>{gBox.showInfo<"$$$$$TabbedPane">;//dosomething}>;5.8Table//KDTable增加表格編輯事件監(jiān)聽pluginCtx.getKDTable<"kdtEntrys">.addKDTEditListener<function<event,methodName>{if<methodName=="editStarted">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$editStarted">;//dosomething}if<methodName=="editStopped">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$EditStopped">;//dosomething}if<methodName=="editStarting">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$EditStarting">;//dosomething}if<methodName=="editStopping">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$EditStopping">;//dosomething}if<methodName=="editValueChanged">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$EditValueChanged">;//dosomething}}>;//KDTable增加鼠標(biāo)事件監(jiān)聽pluginCtx.getKDTable<"kdtEntrys">.addKDTMouseListener<function<event,methodName>{if<event.getClickCount<>==2>{//dosomething}elseif<event.getClickCount<>==1>{//dosomething}}>;//KDTable增加單元格Active事件監(jiān)聽pluginCtx.getKDTable<"kdtEntrys">.addKDTActiveCellListener<function<event,methodName>{vartable=<com.kingdee.bos.ctrl.kdf.table.KDTable>e.getSource<>;varpreLine=event.getPrevRowIndex<>;varline=event.getRowIndex<>;//dosomething}>;第六章使用函數(shù)庫使用較多,比較具有通用性的代碼塊,可將其封裝為函數(shù),在使用時直接調(diào)用函數(shù),以減少代碼量和提高效率。動態(tài)擴(kuò)展平臺中提供了函數(shù)庫的編寫和使用功能。6.1定義函數(shù)庫如下圖所示,在擴(kuò)展定義函數(shù)庫頁簽中,點函數(shù)庫按鈕,新增函數(shù)庫。單擊新增函數(shù)庫函數(shù)據(jù)全路徑單擊新增函數(shù)庫函數(shù)據(jù)全路徑圖5-1首先在根目錄增加類別新增類別據(jù)全路徑新增類別據(jù)全路徑其次,選擇新增類別節(jié)點增加函數(shù),自保存自定義函數(shù)據(jù)全路徑自保存自定義函數(shù)據(jù)全路徑編寫自定義函數(shù)據(jù)全路徑保存,然后該函數(shù)就可以使用了。6.2使用函數(shù)庫和快速插入上下文類似,選中擴(kuò)展點后,在擴(kuò)展定義函數(shù)庫頁簽中,選擇已定義的函數(shù)庫,雙擊,自動生成腳本,如下圖所示,修改所需參數(shù)即可,如$com.kingdee.eas.createNewData<arg0,arg1>我們新建函數(shù),雙擊據(jù)全路徑我們新建函數(shù),雙擊據(jù)全路徑注意:函數(shù)庫是動態(tài)擴(kuò)展方案隔離的。第七章打點提示——快速編寫腳本編寫腳本過程中會用到。為了方便用戶在腳本編輯過程中,能夠快速地,正確地定位包名,類名,以及方法名,減少手工鍵入的錯誤。擴(kuò)展定義支持提示鍵"Alt+/"。7.1環(huán)境準(zhǔn)備在下面路徑自動生成eas_index目錄:服務(wù)端路徑:\kingdee\eas\server\profiles\server1\bin客戶端路徑:\kingdee\eas\client如果以上兩個路徑下均無eas_index目錄,則先生成eas_index目錄。生成eas_index目錄步驟一:在服務(wù)端路徑bin下,執(zhí)行indexServerLib文件,將生成一個eas_index目錄。WindowsOS直接雙擊indexServerLib.bat文件執(zhí)行,LinuxOS通過控制臺執(zhí)行命令shindexServerLib.sh生成eas_index目錄步驟二:將服務(wù)端的eas_index目錄拷貝到本地客戶端\kingdee\eas\client路徑。從服務(wù)器端將eas_index目錄拷貝到此客戶端路徑從服務(wù)器端將eas_index目錄拷貝到此客戶端路徑溫馨提醒:其它客戶端或者新增客戶端如果沒有eas_index目錄,則可以從服務(wù)端或其他客戶端拷貝即可。7.2使用打點提示腳本編輯過程中,可以通過包名或者具體類的前綴查找到特定的類,打點之后,按提示鍵"Alt+/"。輸入過程中,按提示建"Alt+/",根據(jù)輸入前綴搜索匹配的類名,選擇需要的類,雙擊確定輸入過程中,按提示建"Alt+/",根據(jù)輸入前綴搜索匹配的類名,選擇需要的類,雙擊確定第八章調(diào)試腳本在編寫好腳本后,需要運行驗證效果,或需要在腳本執(zhí)行過程中查看變量值,此時需要使用腳本調(diào)試功能。8.1調(diào)試準(zhǔn)備8.1.1客戶端調(diào)試如果想調(diào)試某段客戶端腳本,請在擴(kuò)展定義中勾選"調(diào)試模式執(zhí)行"。這樣,在腳本運行時會彈出腳本調(diào)試窗口。8.1.2服務(wù)器端調(diào)試相比客戶端,如果調(diào)試的腳本為服務(wù)器端腳本,即實體或fa?ade中基于業(yè)務(wù)方法編寫的腳本,則必須在動態(tài)擴(kuò)展平臺中啟動"腳本遠(yuǎn)程調(diào)試",否則將會拋出BOS異常,提示啟動遠(yuǎn)程調(diào)試服務(wù)器。在擴(kuò)展定義中勾選"調(diào)試模式執(zhí)行"在動態(tài)擴(kuò)展平臺中啟動"腳本遠(yuǎn)程調(diào)試"這里啟用腳本遠(yuǎn)程調(diào)試據(jù)全路徑這里啟用腳本遠(yuǎn)程調(diào)試據(jù)全路徑8.2進(jìn)行調(diào)試調(diào)試支持單步執(zhí)行、斷點設(shè)置、變量查看、腳本控制臺等。8.2.1變量查看在調(diào)試過程中需要查看變量,將該變量名輸入至下表變量字段,在對應(yīng)值字段就可以看到變量的當(dāng)前值。8.2.2使用腳本控制臺在調(diào)試中需要執(zhí)行腳本,比如手工修改某變量的值進(jìn)行調(diào)試,就可以使用腳本控制臺。在調(diào)試界面底部,選擇"顯示"模式,在"%"后輸入需要執(zhí)行的腳本表達(dá)式,然后按回車鍵。在‘%在‘%’后輸入要執(zhí)行的腳本,回車執(zhí)行,將顯示腳本執(zhí)行的返回值,如這里返回值是新增值對象的pk首先選擇顯示面板據(jù)全路徑8.3監(jiān)聽事件方法內(nèi)部調(diào)試對于控件添加事件,使用調(diào)試模式斷點也不能進(jìn)入方法內(nèi)部,建議用信息提示的方式處理,就如下例所示:com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$EditStopped">;如果給出提示,則表明事件添加正確。需要查看的變量可通過信息提示出來。//KDTable增加表格編輯事件監(jiān)聽pluginCtx.getKDTable<"kdtEntrys">.addKDTEditListener<function<event,methodName>{if<methodName=="editStopped">{com.kingdee.eas.util.client.MsgBox.showInfo<"$$$$$EditStopped">;}}>;8.4調(diào)試完成在調(diào)試完成后,別忘了把"調(diào)試模式執(zhí)行"勾選去掉,"腳本遠(yuǎn)程調(diào)試"關(guān)閉。第九章常見問題9.1在腳本里添加里添加了監(jiān)聽器,在代碼里刪除監(jiān)聽器的時候的報中斷錯誤問題:在腳本里添加里添加了監(jiān)聽器,在代碼里刪除監(jiān)聽器的時候的報中斷錯誤詳細(xì)描述:在界面加載<onload方法>之后添加了如下腳本:執(zhí)行保存的時候,報如下中斷錯誤:原因分析:在保存之后調(diào)用了loadfields方法,loadfields方法會刪除監(jiān)聽器:而刪除監(jiān)聽器的時候,會調(diào)用EventListenerList〔里面存放的是監(jiān)聽器列表的equal方法,原因就在于EventListenerList[i+1]的equals方法返回的是undefined。解決辦法:在監(jiān)聽器里重載equal方法即可。腳本示例如下:9.2擴(kuò)展腳本不能調(diào)用當(dāng)前類的private方法,不能用super來調(diào)用父類方法問題:擴(kuò)展腳本一般針對于UI和實體的業(yè)務(wù)方法進(jìn)行擴(kuò)展,那腳本中能否調(diào)用當(dāng)前ui或controllerBean中的protected方法?原因分析:不能調(diào)用。擴(kuò)展腳本與當(dāng)前UI或controllerBean沒有繼承關(guān)系,非以BOS二次開發(fā)的ex的方式。擴(kuò)展腳本只能調(diào)用一些公有方法,比如一些工具類的或某些實例的公有方法,不能調(diào)用當(dāng)前類的private方法,不能用super來調(diào)用父類方法。9.3擴(kuò)展腳本中不能使用強(qiáng)制類型轉(zhuǎn)換問題:腳本中定義了varui=<com.kingdee.eas.framework.client.CoreUI>pluginCtx.getUI<>;在運行過程中報錯;原因分析:擴(kuò)展腳本中不支持使用強(qiáng)制類型轉(zhuǎn)換進(jìn)行處理,擴(kuò)展腳本定義變量不必使用類型轉(zhuǎn)換,直接varui=pluginCtx.getUI<>;即可附錄一關(guān)于Rhinohino/Rhinoisanopen-sourceimplementationofJavaScriptwrittenentirelyinJava.ItistypicallyembeddedintoJavaapplicationstoprovidescriptingtoendusers.Rhino語法簡介Rhino是一種使用Java語言編寫的JavaScript的開源實現(xiàn)。與本系列的其他很多語言一樣,Rhino是一種動態(tài)類型的、基于對象的腳本語言,它可以簡單地訪問各種Java類庫。Rhino從JavaScript中借用了很多語法,讓程序員可以快速編寫功能強(qiáng)大的程序。最為明顯的區(qū)別是,Rhino不再使用語句結(jié)束符<;>,放寬了變量聲明規(guī)則,并且極大地簡化了修改和檢索對象屬性的語法〔沒有求助于調(diào)用存取方法。由于Rhino是JavaScript的一種基于Java的實現(xiàn),所以對于Java開發(fā)人員來說,它應(yīng)該特別易于使用。JavaScript的〔以及Rhino的語法非常類似于Java編程語言。這兩種語言都采用了與Java編程語言相似的循環(huán)和條件結(jié)構(gòu),并且遵循類似的語法模式來表示這些結(jié)構(gòu)。歷史簡介在開始學(xué)習(xí)Rhino基礎(chǔ)知識之前,先了解一下有關(guān)JavaScript的起源和目的可能會非常有用,JavaScript為Rhino提供了很多獨特的特性。JavaScript的歷史與Web瀏覽器動態(tài)表示和操作Web頁面內(nèi)容的能力是相符合的。JavaScript的第一個版本〔最初稱為LiveScript是由NetscapeCommunications公司于1995年發(fā)布的,它是NetscapeNavigator2.0Web瀏覽器的一部分。JavaScript打算為程序員提供一種簡單而直觀的方法,編寫一些可以在Web頁面上下文中執(zhí)行任務(wù)的簡單腳本。在隨后的一年中,Microsoft引入了JScript,它自己的用于InternetExplorer的JavaScript端口。這兩個版本的JavaScript都包括一個基于對象的API,稱為文檔對象模型〔DocumentObjectModel或DOM,用以訪問和操作Web頁面的內(nèi)容。JavaScript的第三個實現(xiàn)是一種新的腳本語言,稱為EcmaScript,其目的是對自己和DOM進(jìn)行標(biāo)準(zhǔn)化。不幸的是,Microsoft和Netscape都沒有完全實現(xiàn)EcmaScript標(biāo)準(zhǔn),因此到今天都還存在兼容方面的問題。隨著Java語言在20世紀(jì)90年代末期取得的成功,Netscape計劃發(fā)布Javagator,它是Navigator中一個100%的純Java實現(xiàn)。雖然Javagator從來沒能開花結(jié)果,但是Netscape對JavaScript的移植〔稱為Rhino已經(jīng)經(jīng)過時間的考驗存活了下來。Rhino是JavaScript1.5腳本語言的一個100%的純Java實現(xiàn),不包含DOMAPI。實際上,Rhino有時仍然被當(dāng)作Netscape的基于Java的JavaScript。JavaScript中的"Java"在Rhino的第一個發(fā)行版本中,Netscape顯然想利用Java編程語言所取得的成功。在該公司自己的腳本語言中,很明顯地從Java語言中借用了一些基本的語法。這使得它特別適合Java開發(fā)人員學(xué)習(xí)和使用。例如,考慮一下清單1中給出的Java函數(shù)與Rhino函數(shù)之間的相似性,Rhino函數(shù)測試了給定的數(shù)字是否為素數(shù):清單1.Rhino函數(shù):這個數(shù)字是素數(shù)嗎?functionisPrime<num>{if<num<=1>{print<"Pleaseenterapositiveinteger>=2.">returnfalse}varprime=truevarsqrRoot=Math.round<Math.sqrt<num>>for<varn=2;prime&n<=sqrRoot;++n>{prime=<num%n!=0>}returnprime}除了幾處例外,該程序與Java程序非常類似:圓括號用來分隔代碼塊。for和if結(jié)構(gòu)的語法與Java語言的相同。Rhino與Java語言采用相同的算術(shù)和條件操作符〔例如,對sqrRoot變量的賦值,甚至可以支持類似的訪問其他算術(shù)函數(shù)的方法。Rhino允許使用預(yù)先定義的布爾常量true和false。雖然沒有在這里顯示,但您應(yīng)該注意到,Rhino的while和do...while循環(huán)的結(jié)構(gòu)都與Java語言的相同。Rhino和java語言的具體區(qū)別當(dāng)然,Rhino和Java語言之間有一些顯著的區(qū)別。首先,由于Rhino是采用動態(tài)類型的語言,因此在函數(shù)和變量的聲明中看不到類型。您可以使用function關(guān)鍵字開始函數(shù)的聲明,使用var關(guān)鍵字來聲明局部變量〔這與全局變量不同,但是不用包括正在聲明的變量的類型。Rhino運行庫將在執(zhí)行過程中推斷變量的類型。與Java語言不同,Rhino沒有語句結(jié)束符〔在Java語言中是分號,不過它也可以支持語句結(jié)束符,這是可選的。數(shù)組Rhino中的數(shù)組可以表示為放在方括號中的一串使用逗號分隔的數(shù)值列表。因此,下面就是Rhino中的數(shù)組:numbers=[0,1,2,3,5,24]names=["Mike","Joe","Betty","Therese","LynnMarie"]arrayOfArrays=[1,[2,3],[3,4,5,[6,7]],8]第三個例子說明數(shù)組中的元素不一定非得是簡單類型。聯(lián)合數(shù)組聯(lián)合數(shù)組〔associativearray是另外一種數(shù)據(jù)類型,它可以表示為一個字符串。聯(lián)合數(shù)組在其他語言中有時稱為詞典〔dictionary或hash表,它是一系列關(guān)鍵字-值對,關(guān)鍵字和值使用冒號〔:分隔開。Rhino中的聯(lián)合數(shù)組的作用與Java語言中的java.util.HashMap非常相似。下面是Rhino中的聯(lián)合數(shù)組:person={name:"MikeSquillace",age:37,position:"softwareengineer"}link={text:"IBMHome",url:""}可以使用兩種方法來引用該列表中的元素。要設(shè)置剛才定義的personhash表中的age屬性,您可以這樣使用:person["age"]=39,或者使用person.age=39。要讀取該值并將其保存在變量myAge中,您可以這樣使用:myAge=person["age"],或者使用myAge=person.age.Rhino將典型的有索引的數(shù)組作為一種特殊的聯(lián)合數(shù)組來對待:它們只是一些關(guān)鍵字是正整數(shù)的聯(lián)合數(shù)組。因此,下面這兩行代碼實際上定義的是完全相同的數(shù)組:a1=["fee","fi","fo"]a2={0:"fee",1:"fi",2:"fo"}通過屬性進(jìn)行循環(huán)Rhino提供了一種特殊的循環(huán)結(jié)構(gòu):for...in結(jié)構(gòu),它可以通過聯(lián)合數(shù)組中的屬性進(jìn)行循環(huán)。下列代碼輸出了剛才定義的person聯(lián)合數(shù)組,以及這些屬性的值:for<propinperson>{print<"person["+prop+"]="+person[prop]>}當(dāng)然,我是通過一個類hash表結(jié)構(gòu)實現(xiàn)循環(huán)的,因此不能保證每個屬性及其值都可以輸出。正則表達(dá)式與數(shù)組類似,在Rhino中也可以使用正則表達(dá)式來表示文本,使用Perl和其他腳本語言的用戶應(yīng)該非常熟悉其語法。在Rhino中,當(dāng)表示為文字值時,正則表達(dá)式是通過正向斜線〔/來分隔的。在Rhino中,正則表達(dá)式被傳遞給字符串對象的方法,以便更簡單地執(zhí)行文本處理任務(wù)。例如,下面的第一行代碼定義了一個正則表達(dá)式,它可以匹配算術(shù)表達(dá)式中的正整數(shù)和標(biāo)準(zhǔn)算術(shù)操作符。第二行代碼通過調(diào)用match函數(shù)處理給定的表達(dá)式,如下所示:tokenExpr=/\d+|[\+\-\*\/]/g"38-4+98/5".match<tokenExpr>結(jié)果是生成一個Rhino字符串?dāng)?shù)組,數(shù)組的元素包含以下內(nèi)容:"38","-","4","+","98","/",and"5"函數(shù)顯式聲明最后,Rhino提供了函數(shù)數(shù)據(jù)類型。正如前面介紹的那樣,Rhino作為第一類數(shù)據(jù)類型支持函數(shù)——可以從函數(shù)中返回,也可以傳遞到函數(shù)中,還可以在變量聲明中使用。因此,我可以在解釋器提示符中編寫下面的代碼,并得到結(jié)果9,這是定義平方函數(shù)的期望結(jié)果:square=function<x>{returnx*x}按照這個平方函數(shù)的定義,我輸入了以下內(nèi)容:square<3>這樣定義的函數(shù)不但可以用來處理文本,還可以用來處理其他數(shù)據(jù)。例如,我可以定義一個如下所示的聯(lián)合數(shù)組函數(shù):fnList={square:function<x>{returnx*x},cube:function<x>{returnx*x*x},sqrt:function<x>{returnMath.sqrt<x>}}然后我可以對數(shù)組中的列表循環(huán)調(diào)用該函數(shù),輸出每個函數(shù)的值,就像它是一個數(shù)字一樣。例如,我可以編寫下面的代碼:for<fnNameinfnList>{print<"The"+fnName+"of"+3+"is"+fnList[fnName]<3>>}將獲得如下所示結(jié)果:Thesquareof3is9thesqrtof3is1.7320508075688772Thecubeof3is27Rhino中的對象在使用聯(lián)合數(shù)組并且將函數(shù)表示為文本之后,就可以在Rhino中將任何對象表示為聯(lián)合數(shù)組。實際上,對象的文本表示只不過是一個聯(lián)合數(shù)組,它可能包含某些函數(shù)作為一些值。下面這個例子將展示在Rhino中使用對象是多么簡單,Rhino處理這些對象表現(xiàn)得多么強(qiáng)大。在開始這個例子之前,請再次考慮personhash表的例子:person={name:"MikeSquillace",age:37,position:"softwareengineer"}在Rhino中,這是一個聯(lián)合數(shù)組的文本表示,不過更確切的說,它是一個對象的文本表示。這種表示在Rhino中也稱為對象初始化。剛才定義的值的類型是由解釋器在輸入上面的定義之后根據(jù)下面的代碼進(jìn)行判斷的:[objectObject]上面的代碼說明了變量person中存放的值是Object類型的。添加方法然后,我將向您展示,在重新定義person對象,以包含檢索該對象的第一個名稱的函數(shù)時,會出現(xiàn)什么樣的情況。我將通過編寫下面的代碼來展示這一點:person={name:"MikeSquillace",age:37,position:"softwareengineer",getFirstName:function<>{return.split<"">[0]}}該函數(shù)〔更確切地說是方法getFirstName使用了this指針來引用當(dāng)前的對象,并對name屬性調(diào)用split方法。然后,split方法返回一個數(shù)組,其中保存了根據(jù)空格字符將給定字符串分割成子字符串的結(jié)果。最后取得該數(shù)組的第一個值并返回。我們已經(jīng)很熟悉調(diào)用新的getFirstName函數(shù)的方式,如下所示:person.getFirstName<>圓括號告訴Rhino解釋器我正在調(diào)用一個函數(shù),而不是簡單地引用一個對象的屬性。然而要注意的是,該函數(shù)本身也只是另一個person對象的屬性,如果沒有圓括號,它將引用一個未定義的值。添加更多的方法Rhino還可以允許動態(tài)地為對象添加屬性和方法。例如,如果想添加一個檢索通過person對象表示的某人名字的方法,那么只需簡單輸入下列代碼即可:person.getLastName=function<>{return.split<"">[1]}現(xiàn)在,當(dāng)我輸入下面的方法時,就可以得到想要的結(jié)果,在本例中,這個結(jié)果是"Squillace":person.getLastName<>〔注意,您可以使用delete操作符來刪除任何屬性,例如deleteperson.getLastName。使用原型雖然上面這個例子非常有趣,但是您可能不希望一直使用對象初始化來定義個別某些人。幸運的是,Rhino提供了另外一種創(chuàng)建對象的方法:使用構(gòu)造函數(shù)〔constructorfunction。例如,下面的函數(shù)可以作為一名Person對象的構(gòu)造函數(shù):functionPerson<name,age,job>{=name||"<unknown>"this.age=agethis.job=job||"<unemployed>"this.getFirstName=function<>{return.split<"">[0]}this.getLastName=function<>{return.split<"">[1]}}擁有構(gòu)造函數(shù)之后,就可以使用new操作符來創(chuàng)建對象了,如下所示:mike=newPerson<"MikeSquillace",37,"softwareengineer">任何函數(shù)都可以用作構(gòu)造函數(shù),不過通常希望使用定義〔使用this指針來引用正在定義的對象對象屬性的函數(shù)以及為這些屬性賦值〔或函數(shù)的函數(shù)作為構(gòu)造函數(shù)。無類編碼作為一個Java開發(fā)人員,您很可能會認(rèn)為下一個步驟是在Rhino中定義Person類。實際上,Rhino并不需要這樣定義類——因為它根本就不使用類!在Rhino中既沒有類,也沒有類的實例,只有特定的對象。當(dāng)調(diào)用new操作符時,構(gòu)造函數(shù)就為對象創(chuàng)建一個所謂的原型〔prototype;也就是說,它創(chuàng)建了一個模板〔template,從中構(gòu)建給定類型的對象。基于類的語言與基于原型的語言的比較諸如C++和Java之類的基于類的語言使用一個類定義來表示一組具有特定屬性集的對象,包括用來表示類的實例和這些實例可以執(zhí)行的任務(wù)類型的數(shù)據(jù)。一旦編寫并編譯了類定義,就不能在運行時再對其進(jìn)行修改,該列的所有實例都包含該類中定義的數(shù)據(jù)和方法〔也可能只有這些數(shù)據(jù)或方法。在這種情況下,所有的類都是Class類的實例?;谠偷恼Z言并不區(qū)分類和實例;它們只識別基于原型或模板的特殊對象。原型定義了對象初始化時使用的屬性?;谠偷膶嵗膶傩砸约霸捅旧碓谌魏螘r間都可以修改。因此,不需要一個"類"對象或數(shù)據(jù)類型。從某種意義上來說,我們可以認(rèn)為基于原型的語言是基于對象的差異性,而不是基于對象的共同性。在諸如Rhino之類的基于原型的語言中,您可以修改特定對象的屬性,或者其原型的屬性。例如,如果想為剛才定義的mike對象中添加一個特殊屬性,可以使用下面的方法:mike.disability="blind"我還可以通過引用Person構(gòu)造函數(shù)的原型屬性來修改Person的屬性。如果以后想為所有從這個構(gòu)造函數(shù)中派生出來的對象都添加一個birthdate屬性,可以使用下面的方法:Ptotype.birthdate=null然后使用:mike.birthDate=newDate<66,10,3>//monthsarezero-based:thisis11/3/66還要注意基于Person原型創(chuàng)建的新對象都有birthdate屬性,因此下面的代碼是有效的:jami=newPerson<"JamiBomer",25,"unemployed">jami.birthdate=newDate<79,5,28>附錄二案例腳本//客戶端在擴(kuò)展點提交時給F7控件增加監(jiān)聽器vareasNames=JavaImporter<>;easNames.importPackage<P.kingdee.bos.ctrl.extendcontrols>;easNames.importPackage<P.kingdee.bos>;with<easNames>{varroadMap=pluginCtx
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年濟(jì)南北山糧庫有限公司公開招聘勞務(wù)派遣工作人員崗位備考題庫及答案詳解一套
- 2026年第十三師中級人民法院聘用制書記員招聘備考題庫及參考答案詳解1套
- 臨泉縣面向2026屆公費師范畢業(yè)生招聘教師備考題庫完整參考答案詳解
- 企業(yè)采購管理制度
- 中學(xué)學(xué)生社團(tuán)活動經(jīng)費管理執(zhí)行制度
- 中學(xué)教師職稱晉升制度
- 養(yǎng)老院收費標(biāo)準(zhǔn)及退費制度
- 2026年重慶醫(yī)科大學(xué)附屬康復(fù)醫(yī)院關(guān)于黨政辦公室黨建、宣傳干事、醫(yī)保辦工作人員招聘備考題庫及一套答案詳解
- 2026年龍巖市武平縣招聘動物防疫專員的備考題庫及參考答案詳解一套
- 交通設(shè)施安全檢測制度
- 半導(dǎo)體產(chǎn)業(yè)人才供需洞察報告 202511-獵聘
- 電梯救援安全培訓(xùn)課件
- 2025年青島市國企社會招聘筆試及答案
- 2026屆江西省撫州市臨川區(qū)第一中學(xué)高二上數(shù)學(xué)期末考試模擬試題含解析
- 云南省大理州2024-2025學(xué)年七年級上學(xué)期期末考試數(shù)學(xué)試卷(含解析)
- 物業(yè)管理法律法規(guī)與實務(wù)操作
- (16)普通高中體育與健康課程標(biāo)準(zhǔn)日常修訂版(2017年版2025年修訂)
- 電力工程施工組織措施
- 五年級數(shù)學(xué)上冊計算題專項練習(xí)
- 人工智能賦能制造業(yè)的變革
- 腹腔鏡下前列腺癌根治術(shù)護(hù)理查房課件
評論
0/150
提交評論