翻譯|使用教程|編輯:楊鵬連|2020-07-03 10:36:50.867|閱讀 294 次
概述:本頁(yè)介紹如何通過(guò)替換實(shí)例上的方法(JavaScript的功能)或定義子類來(lái)覆蓋方法。您不應(yīng)修改任何GoJS類的原型。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
GoJS是一款功能強(qiáng)大,快速且輕量級(jí)的流程圖控件,可幫助你在JavaScript 和HTML5 Canvas程序中創(chuàng)建流程圖,且極大地簡(jiǎn)化您的JavaScript / Canvas 程序。
GoJS可以通過(guò)多種方式進(jìn)行擴(kuò)展。更改標(biāo)準(zhǔn)行為的最常見(jiàn)方法是在GraphObject,Diagram,CommandHandler,Tool或Layout上設(shè)置屬性。但是,當(dāng)不存在此類屬性時(shí),您可能需要覆蓋CommandHandler,Tool,Layout,Link或Node的方法。API參考中記錄了可以覆蓋的方法。
請(qǐng)注意,擴(kuò)展類的API可能會(huì)隨任何版本(甚至是點(diǎn)發(fā)行)而更改。如果打算在生產(chǎn)環(huán)境中使用擴(kuò)展名,則應(yīng)將代碼復(fù)制到自己的源目錄中。
除了我們的示例外,GoJS還提供了一個(gè)擴(kuò)展庫(kù),展示了自定義工具和布局的創(chuàng)建。這些類和示例已被翻譯成TypeScript,可從此處獲得../extensionsTS/。這些擴(kuò)展類是UMD模塊。他們使用../release/go.js圖書(shū)館。擴(kuò)展類還可以作為ES6模塊在以下位置獲得../extensionsJSM/:這些使用../release/go-module.js庫(kù)。我們建議您將所需的文件復(fù)制到項(xiàng)目中,以便可以調(diào)整它們對(duì)“ go.js”庫(kù)的引用方式,并可以將它們包含在自己的構(gòu)建和打包過(guò)程中。
命令處理程序
通過(guò)覆蓋CommandHandler,您可以更改默認(rèn)功能并創(chuàng)建自己的鍵綁定。有關(guān)更多信息,請(qǐng)參見(jiàn)“ 命令 ” 簡(jiǎn)介頁(yè)。但是,下面顯示的用于覆蓋“工具和布局”上的方法的技術(shù)也適用于CommandHandler。
工具和布局
GoJS使用許多工具和布局在節(jié)點(diǎn)和鏈接上進(jìn)行操作,所有這些工具和布局都是Tool和Layout類的子類。有關(guān)工具的更多信息,請(qǐng)參見(jiàn)工具的簡(jiǎn)介頁(yè)面;有關(guān)布局的更多信息,請(qǐng)參見(jiàn)布局的簡(jiǎn)介頁(yè)面。
可以修改工具,也可以將其替換或添加到Diagram.toolManager中。所有工具必須繼承自Tool類或繼承自Tool的類。
我們的一些示例(例如Pipes示例)包含自定義工具的示例。擴(kuò)展庫(kù)中提供了更多自定義工具示例。這些類和示例的TypeScript版本可以在../extensionsTS/中找到。這些自定義工具類也可以作為ES6模塊在../extensionsJSM/中使用。布局可以被修改,或者它們可以通過(guò)設(shè)置使用Diagram.layout或Group.layout。所有布局都必須從Layout類或從Layout繼承的類繼承。
我們的一些示例(例如“ 解析樹(shù)”示例)包含自定義布局的示例。擴(kuò)展庫(kù)中提供了更多自定義布局示例。這些類的TypeScript版本可以在../extensionsTS/中找到。這些自定義布局類也可以在../extensionsJSM/中的ES6模塊中使用。
在不定義子類的情況下覆蓋方法
通常,我們可以避免完整地繼承Tool的子類,而僅重寫單個(gè)方法。當(dāng)我們想對(duì)方法的行為做些小改動(dòng)時(shí),這是很常見(jiàn)的。這里我們展示了如何覆蓋ClickSelectingTool ,standardMouseSelect方法通過(guò)修改特定圖表的工具實(shí)例。
也可以用這種方式覆蓋Layout方法,但很少這樣做——布局幾乎總是被子類化。對(duì)于Group.layout值的布局,無(wú)法完成此操作,因?yàn)檫@些布局可能會(huì)被復(fù)制且無(wú)法共享。因?yàn)?我們不是在創(chuàng)造一個(gè)新的(子)類,所以我們直接在圖的ClickSelectingTool上設(shè)置這個(gè)方法,這個(gè)工具是通過(guò)它的工具管理器引用的。以這種方式覆蓋方法的典型腳手架如下:
var tool = diagram.toolManager.clickSelectingTool; tool.standardMouseSelect = function() { //可能在 // ... 之前做其他事情 //注意在此類函數(shù)中使用“ this”! //如果您想要正常的行為,請(qǐng)調(diào)用基本功能。 //注意對(duì)原型的引用, //以及對(duì)“ call”的調(diào)用,將其傳遞為“ this”。 go.ClickSelectingTool.prototype.standardMouseSelect.call(tool); //也許在 // 之后做其他事情... }作為一個(gè)具體的例子,我們將覆蓋工具standardMouseSelect只選擇寬度和高度小于50圖單元的節(jié)點(diǎn)和鏈接。這意味著我們必須使用圖表找到要選擇的對(duì)象。findPartAt,檢查它的邊界,如果邊界太大就退出。否則,我們調(diào)用基本功能來(lái)進(jìn)行選擇。
diagram.nodeTemplate = $(go.Node,“ Auto”, $(go.Shape,“ Rectangle”, { fill:“ white” }, 新建 go.Binding(“ fill”,“ color”)), $(go.TextBlock, { margin:5 }, 新的 go.Binding(“ text”,“ key”)) ); var tool = diagram.toolManager.clickSelectingTool; tool.standardMouseSelect = function() { var diagram = tool.diagram; var e = diagram.lastInput; //以選擇包含組如果Part.canSelect()為假 VAR curobj = diagram.findPartAt(e.documentPoint,false); 如果(curobj!== null){ var bounds = curobj.actualBounds; //如果邊界大于50寬度或高度, 則結(jié)束選擇過(guò)程,如果(bounds.width> 50 || bounds.height> 50){ //如果這是沒(méi)有修飾符的左鍵單擊,則我們希望執(zhí)行相同的操作仿佛 // //點(diǎn)擊“圖表”背景,因此 如果((e.left &&!e.control &&!e.shift){ diagram.clearSelection(); } //然后返回,這樣就不會(huì)調(diào)用基本功能 return; } } //否則,調(diào)用基本功能 go.ClickSelectingTool.prototype.standardMouseSelect.call(tool); } diagram.model = new go.Model([ { 鍵:“ Alpha”,顏色:“淺藍(lán)色” }, { 鍵:“ Epsilon”,顏色:“薊” }, { 鍵:“ Psi”,顏色:“ lightcoral” }, { 鍵:“伽瑪”,顏色:“ 淺綠色” } ]);
運(yùn)行此代碼,我們看到“ Epsilon”和“ Gamma”節(jié)點(diǎn)都不可選,因?yàn)樗鼈兊膶挾榷即笥?0。請(qǐng)注意,此自定義工具不會(huì)更改其他可能選擇的工具的行為,例如DraggingTool或該DragSelectingTool。
通過(guò)子類化布局覆蓋方法
可以將布局子類化以創(chuàng)建自定義布局,這些自定義布局繼承現(xiàn)有布局的屬性和方法。GoJS的傳統(tǒng)JavaScript中的子類化需要幾個(gè)關(guān)鍵步驟:
function CascadeLayout() { //注意直接調(diào)用構(gòu)造函數(shù),不使用“原型” go.Layout.call(this); //在“ this”上添加新屬性 } go.Diagram.inherit(CascadeLayout,go.Layout); // //注意在原型 CascadeLayout.prototype.doLayout = function(coll)上設(shè)置方法 { //布局邏輯在這里。 //您可以可靠地使用“ this”來(lái)引用 //調(diào)用此方法的布局實(shí)例。 }請(qǐng)注意,如果您使用現(xiàn)代JavaScript(ECMAScript 6)或TypeScript進(jìn)行編寫,則可以使用更新的語(yǔ)法來(lái)定義類:
導(dǎo)出 類 CascadeLayout 擴(kuò)展 go。布局 { //在此聲明和初始化新的數(shù)據(jù)屬性(字段) constuctor(){ super(); //其他初始化可以在這里完成 } //(可選)在此處定義屬性獲取器和設(shè)置器 //覆蓋或定義方法 公共doLayout(coll){ //布局邏輯在這里。 } }布局通常需要用作布局選項(xiàng)的其他屬性。要向中添加“ offset”屬性CascadeLayout,我們將使用下劃線成員為私有的約定,并在構(gòu)造函數(shù)中設(shè)置默認(rèn)值:
function CascadeLayout() { go.Layout.call(this); 此 ._offset = 新 go.Size(12,12); }然后,我們使用Object.defineProperty“公開(kāi)”獲取器和設(shè)置器。Getter和Setters使我們能夠進(jìn)行類型檢查并具有副作用。此設(shè)置器確保偏移值是一個(gè)go.Size對(duì)象,并且僅在更改值后才使布局無(wú)效。
Object .defineProperty(CascadeLayout.prototype,“ offset”,{ get:function() { 返回 此 ._offset; }, get:function(val) { if(!(val instanceof go.Size)){ 拋出 新 錯(cuò)誤(“ CascadeLayout.offset的新值必須是Size,而不是:” + val); } if(!this ._offset.equals(val)){ this ._offset = val; 這個(gè) .invalidateLayout(); } } });如果您使用ECMAScript 6或TypeScript進(jìn)行編寫,則可以定義屬性getter和setter。
get offset(){ 返回 此 ._offset; } set offset(val){ if(!(val instanceof go.Size)){ 拋出 新 錯(cuò)誤(“ CascadeLayout.offset的新值必須為Size,而不是:” + val); } if(!this ._offset.equals(val)){ this ._offset = val; 這個(gè) .invalidateLayout(); } }如果可以將布局用作Group.layout的值,則需要確??梢哉_復(fù)制在Group模板中設(shè)置的實(shí)例。
CascadeLayout.prototype.cloneProtected = function(復(fù)制) { go.Layout.prototype.cloneProtected.call(this,copy); copy._offset = 此 ._offset; }最后,我們將定義一個(gè)Layout.doLayout,確保查看文檔并適應(yīng)所有可能的輸入,因?yàn)閐oLayout具有一個(gè)參數(shù),可以是Diagram,Group或Iterable集合。
/ ** * @構(gòu)造函數(shù) * @擴(kuò)展布局 * @類 *此布局按offset屬性指定的級(jí)聯(lián)排列節(jié)點(diǎn) * / function CascadeLayout() { go.Layout.call(this); 此 ._offset = new go.Size(12,12); } go.Diagram.inherit(CascadeLayout,go.Layout); CascadeLayout.prototype.cloneProtected = function(復(fù)制) { go.Layout.prototype.cloneProtected.call(this,copy); copy._offset = 此 ._offset; } Object .defineProperty(CascadeLayout.prototype,“ offset”,{ get:function() { 返回 此 ._offset; }, get:function(val) { if(!(val instanceof go.Size)){ 拋出 新 錯(cuò)誤(“ CascadeLayout.offset的新值必須是Size,而不是:” + val); } if(!this ._offset.equals(val)){ this ._offset = val; this .invalidateLayout(); } } }); / ** *此方法放置所有節(jié)點(diǎn),并忽略所有鏈接。 * @this {CascadeLayout} * @param {Diagram | Group | Iterable}將零件集合收集到布局中。 * / CascadeLayout.prototype.doLayout = function(coll) { //獲取要布置的節(jié)點(diǎn)和鏈接 var parts = this .collectParts(coll); //從布局的起點(diǎn)開(kāi)始布局,這是從Layout繼承的屬性 var x = this .arrangementOrigin.x; var y = 此 .arrangementOrigin.y; var offset = this .offset; var it = parts.iterator; while(it.next()){ var node = it.value; if((node instanceof go.Node))continue ; //忽略鏈接 node.move(new go.Point(x,y)); x + = offset.width; y + = offset.height; } } // CascadeLayout的結(jié)尾 //常規(guī)圖設(shè)置: diagram.layout = new CascadeLayout(); diagram.nodeTemplate = $(go.Node,“ Auto”, $(go.Shape,“ Rectangle”, { fill:“ white” }, new go.Binding(“ fill”,“ color”)), $(go.TextBlock, { margin:5 }, new go.Binding(“ text”,“ key”)) ); diagram.model = new go.Model([ { 鍵:“ Alpha”,顏色:“淺藍(lán)色” }, { 鍵:“貝塔”,顏色:“薊” }, { 鍵:“ Delta”,顏色:“ lightcoral” }, { 鍵:“伽瑪”,顏色:“ 淺綠色” } ]);
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: