我目前正在開發一個自定義 VSCode 擴展,它從遠程 API 獲取資料并在自定義樹視圖中呈現資料。樹視圖本身允許與 API 互動,即根據一些預定義的條件過濾結果,例如搜索詞或回應是否附加了一些檔案,動態添加新節點或洗掉或更新樹中的現有節點.
為簡單起見,我創建了一個自己的
GIF 已調整大小以適應 2MB 的限制,因此會產生丑陋的偽影
在 a 上顯示TreeView
由 custom 定義的命令的動作圖示時,在TreeDataProvider
a 上TreeItem
通過定義如下內容相當簡單:
...
{
"contributes":
"commands": [
{
"command": "extension.myTreeView.filter",
"title": "Filter",
"icon": "$(filter)",
"when": "view == extension.myTreeView"
},
{
"command": "extension.myTreeView.resetFilter",
"title": "Reset Filter",
"shortTitle": "Reset",
"icon": "$(close)",
"enablement": "view == extension.myTreeView && extension.myTreeView.hasFilter",
"when": "view == extension.myTreeView && extension.myTreeView.hasFilter"
},
{
"command": "extension.myTreeView.delete",
"title": "Delete Item",
"shortTitle": "Delete",
"icon": "$(trash)",
"when": "view == extension.myTreeView && viewItem == archive"
}
...
],
"menus": {
"view/title": [
{
"command": "extension.myTreeView.filter",
"when": "view == extension.myTreeView"
"group": "navigation@1"
},
{
"command": "extension.myTreeView.resetFilter",
"when": "view == extension.myTreeView",
"group": "navigation@2"
},
...
],
"view/item/context": [
...
{
"command": "extension.myTreeView.delete",
"when": "view == extension.myTreeView && viewItem == archive",
"group": "inline@3"
}
]
}
},
...
在package.json
檔案中,我不知何故難以為針對特定專案本身的命令添加啟用條件。即樹允許下載包含在(或附加到)由節點表示的專案中的一些檔案。這些節點可能有也可能沒有附加檔案,因此啟用下載操作僅對至少有檔案要下載的節點有意義。雖然通常下載該內容或呈現用于觸發下載操作的按鈕不是問題,但該命令的啟用選項是我有點無能為力的地方。
我通過為此類樹節點定義不同型別的 's 暫時“解決”了該問題contextValue
,一種用于包含檔案的存檔,另一種用于不下載檔案。雖然這通常似乎解決了這個問題,但它 a) 感覺不合適并且 b) 導致下游問題。想象一下,可以鎖定檔案,以防止不屬于檔案被鎖定的組的用戶進行實際下載。這只是一個虛構的案例,但應該說明您最終可能會在該contextValue
變數中獲得屬性欄位的組合,您或多或少需要在該啟用陳述句中決議。并且每個進一步可能的背景關系值選項都必須貫穿整個整體commands
和menus
這樣的定義:
...
{
"command": "extension.myTreeView.delete",
"when": "view == extension.myTreeView && viewItem == archive || viewItem == archiveWithFiles || viewItem == ...",
"group": "inline@2"
},
...
一般來說,自定義背景關系變數,例如hasFilter
上面顯示的示例命令配置,可以在enablement
andwhen
子句中使用,可用于顯示/隱藏或啟用/禁用某些命令,但這些似乎僅適用于整個樹本身而不是特定的樹項。即示例應用程式使用以下代碼resetFilter
根據是否定義了過濾器來啟用/禁用命令:
...
public async updateFilter(filter: Filter): Promise<void> {
this.filter = filter;
await commands.executeCommand("setContext", TestTreeDataProvider.CONTEXT_HAS_FILTER, true);
this.items = [];
this._onDidChangeTreeData.fire();
}
private async resetFilter(): Promise<void> {
this.filter = undefined;
await commands.executeCommand("setContext", TestTreeDataProvider.CONTEXT_HAS_FILTER, false);
this.items = [];
this._onDidChangeTreeData.fire();
}
這是有效的,因為這或多或少是對樹本身的全域操作,并且它具有單一的屬性來源。但是這樣的背景關系值可能只具有分配給它們的基本型別或物件,其中僅檢查該物件的鍵(又名屬性名稱)是否可用in
條款。我可能會為每個生成的樹項創建自定義背景關系變數,但是我需要某種形式的尋址機制,因為每個背景關系值名稱必須不同,否則它們會被下一個節點的背景關系值覆寫。由于樹可以容納大量節點,因此我覺得為每個節點添加背景關系值也不是很高效。最后,這里似乎缺少一種將函式定義為背景關系值的方法,該方法允許當前節點(TreeItem 或節點所指的實際物件)作為輸入,并且需要回傳一個基本型別為輸出,即true
確定false
是否應該啟用該專案。
雖然這里的這個 SO 問題可能聽起來很相似,但它實際上要求禁用整個樹項節點,因為我只希望可以根據某個樹項的當前屬性值啟用/禁用可以在該樹項上執行的命令。一些TreeItem
基于背景關系的 s 樣式可以通過FileDecorationProvider
's 來完成。該問題也是 VSCode 中的一個錯誤的結果,該錯誤似乎不會強制重新渲染對啟用保護所做的任何更改。
我覺得在這個問題上必須有一個更簡單的解決方案,這就是我在這里問的原因。簡而言之,如何根據當前樹項的背景關系(由該節點持有的屬性或在該節點上執行的函式)在 Visual Studio Code 中啟用/禁用命令?
uj5u.com熱心網友回復:
您現在將型別描述作為 TreeItem 的背景關系值。
為什么不將允許的操作也放在背景關系值中:
archive_Del
archive_Read_Update
when
然后在子句中使用這個
{
"command": "extension.myTreeView.delete",
"when": "view == extension.myTreeView && viewItem =~ /^.*_Del.*$/",
"group": "inline@2"
}
{
"command": "extension.myTreeView.read",
"when": "view == extension.myTreeView && viewItem =~ /^.*_Read.*$/",
"group": "inline@2"
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/467671.html