テキストに行番号や接頭辞・接尾辞を挿入する Angular アプリを作った

テキストエディタによっては「矩形選択」が出来たりするが、連番の挿入が柔軟にできるエディタが少ない気がしたのと、「そういうエディタねえよ」っていう環境もあると思うので、Angular アプリとして作ってみた。

行番号は整形せず入れたり、0 パディングして入れたり、右寄せで入れたりできる。

8 コレが通常の行番号挿入
9 こういう感じ
10 こういう感じ

08 コレが 0 パディングのイメージ
09 こういう感じ
10 こういう感じ

 8 コレが右寄せのイメージ
 9 こういう感じ
10 こういう感じ

行番号とは別に、全ての行の最初と最後に、固定文言を入れられるオプションも用意した。行番号を「出力しない」にしておけば、テキストの各行の接頭辞と接尾辞を一括付与するだけのツールとしても使える。

値の変更は ngDoCheck() で監視して、自動的に結果を出力するようにしているのだが、一つつまづいたのはラジオボタンの実装。

今回の画面でいうと、2つの別々の項目に、3個ずつラジオボタンが置いてあるので、2項目を区別しないといけない。

<input type="radio" [(ngModel)]="options.lineNumberStyle" value="none"> 整形なし
<input type="radio" [(ngModel)]="options.lineNumberStyle" value="zeroPadding"> 0 パディング
<input type="radio" [(ngModel)]="options.lineNumberStyle" value="alignRight"> 右寄せ

<!-- ↑ と ↓ は別々の項目 -->

<input type="radio" [(ngModel)]="options.lineNumberPosition" value="beforeSrc"> 入力値の前
<input type="radio" [(ngModel)]="options.lineNumberPosition" value="afterSrc"> 入力値の後
<input type="radio" [(ngModel)]="options.lineNumberPosition" value="none"> 出力しない

しかし、上述のように実装したところ、2項目の値が共有されてしまうというおかしな挙動になっていた。ngDoCheck() を使わなければ、それぞれの [(ngModel)] の値は別々に保持されるのに、妙な動きだった。

コレを解消するには、name 属性値を別々に付与してやると良い。

<input type="radio" [(ngModel)]="options.lineNumberStyle" name="optionsLineNumberStyle" value="none"> 整形なし
<input type="radio" [(ngModel)]="options.lineNumberStyle" name="optionsLineNumberStyle" value="zeroPadding"> 0 パディング
<input type="radio" [(ngModel)]="options.lineNumberStyle" name="optionsLineNumberStyle" value="alignRight"> 右寄せ

<!-- TypeScript 側では一切参照しないが、name 属性を別々に付与すると、[(ngModel)] の区別が付くようになる -->

<input type="radio" [(ngModel)]="options.lineNumberPosition" name="optionsLineNumberPosition" value="beforeSrc"> 入力値の前
<input type="radio" [(ngModel)]="options.lineNumberPosition" name="optionsLineNumberPosition" value="afterSrc"> 入力値の後
<input type="radio" [(ngModel)]="options.lineNumberPosition" name="optionsLineNumberPosition" value="none"> 出力しない

コレで上手く行った。

こうしたテキスト処理系のアプリは、個々の機能は比較的簡単に作れる上に、それなりに繰り返し使う用途が出てくるので、手元に置いておくのは便利かも。