はじめに
今回はサーバスクリプトで選択肢を制御するメソッドであるcolumns.AddChoiceHashをキーなしで値だけで扱いが可能な様に拡張する方法を紹介します。
今回紹介する方法は本体コードへの改変が必要になります。そのため、実際に本記事に記載されている方法を試すには、Visual StudioとVisual Studio Codeなどのビルドして実行するための環境が必要です。ビルド環境については、公式レポジトリのドキュメントを参照してください。
下調べ
サーバスクリプトはImplem.Pleasanter/Libraries/ServerScriptsに格納されているファイル群に定義されています。今回はcolumns配下のメソッドなのでServerScriptModel.csに格納されています。
サーバスクリプトのメソッド群は$ps.から始まるものはClearScriptで、そうでないものはC#で実装されています。
今回のAddChoiceHashの部分を見てみます。
引数2つで、キーと値を設定するようになっています。
この部分がプリザンター内部での選択肢としてどのように扱われるかを見てみましょう。実際に値がセットされているChoiceHashへの参照を追いかけていきます。
columnsにセットされた値はここで処理がされます。ChoiceHashを処理しているのは、次の場所です。
重要な場所はクライアントサイドに渡すための値としてモデルを詰め替えているところになります。
ここです。Choiceモデルに中身を詰め替えています。
これは項目ごとの選択肢一覧やWikiを選択肢化したときにも使われるモデルになります。
今回やりたいことは選択肢一覧で値だけを設定することと同じなので、選択肢一覧をChoiceモデルに詰め替える処理の部分を見てみれば、どのように設定すれば良いか分かりそうです。
では、選択肢一覧をChoiceモデルに詰め替えているところを見てみます。
ここになります。選択肢として与えられた値はセパレータで分割され配列に格納されます。_序数で始まる拡張メソッドは配列のN番目に値があればそれを返し、配列の範囲外であったり値がなければnullを返すようになっています。Strings.CoalesceEmptyでは第1引数の値がnullやemptyでなければそれを返し、それらであれば第2引数の値を返すようになっています。
この処理を通過した後、選択値として与えられた値がどのように格納されるかは次の表の通りになります。
| 選択肢設定 | Value |
Text |
TextMini |
CssClass |
Style |
|---|---|---|---|---|---|
完了 |
完了 | 完了 | 完了 | ||
900,完了 |
900 | 完了 | 完了 | ||
900,完了,完 |
900 | 完了 | 完 | ||
900,完了,完,status-closed |
900 | 完了 | 完 | status-closed | |
900,完了,完,status-closed,color:red; |
900 | 完了 | 完 | status-closed | color:red; |
値だけ与えるときはValueとText、TextMiniに同値を与えれば良いということが分かります。
先ほどのサーバスクリプトのcolumnsに関する処理でChiceモデルへの値の詰め替えを行っているところを再度見てみます。
実際の詰め替え処理を行っているのはChoiceモデルのコンストラクタなのでこれを見てみます。
今回、詰め替え部分では第3引数以下を省略しているので、次の様に値がセットされます。
| サーバスクリプト側 | 選択肢実態 |
|---|---|
o.Key.ToString() |
Value |
o.Value?.ToString() |
Text |
o.Value?.ToString() |
TextMin |
この表と選択肢一覧が展開された場合の表を照らし合わせると、サーバスクリプト側ではKeyとValueに同値をセットしてやれば良いということが分かります。
実装
実際に実装してみましょう。今回だとオーバーロードを使って実装するパターンと、デフォルト引数を使って実装するパターンの2通りでいけそうですね。せっかくなので2通りで考えてみます。
オーバーロード
//オーバーロードを追加する
public void AddChoiceHash(object key) => AddChoiceHash(key, key);
//下記は既存コード
public void AddChoiceHash(object key, object value)
{
if (ChoiceHash == null)
{
ChoiceHash = new Dictionary<object, object>();
}
ChoiceHash.Add(key, value);
_choiceHashChanged = true;
}
デフォルト引数
public void AddChoiceHash(object key, object value = null)
{
value ??= key; //ここを追加
if (ChoiceHash == null)
{
ChoiceHash = new Dictionary<object, object>();
}
ChoiceHash.Add(key, value);
_choiceHashChanged = true;
}
完全に好みですね。個人的にはどっちでも良いかなといった感じです。実際に本体コードへのコントリビュートをする場合だと、デフォルト引数のほうが優勢かな?といったところです。
まとめ
今回はサーバスクリプトのcolumns.AddChoiceHashの拡張の方法を紹介してみました。本体コードの改修はサーバスクリプト回りから手をつけるのがわかりやすくてオススメです。皆さんのコントリュビュートをお待ちしています!!