↓先日投稿した記事↓の続きです。 ngmt83.hatenablog.com
AngularでJsBarcodeというモジュールを使う方法を紹介します。
AngularからJsBarcodeを使用する方法(基本)
ここに書いてある通りで非常に簡単ですが、Angularに組み込むための手順があるので軽く説明します。
- npm install (yarn add)
- 使用するcomponentでimport
- バーコードを表示するためのhtml要素を用意
- html要素にJsBarcodeを設定
これだけです。簡単ですね。(なのにちょっとハマりました)
サンプルをこちらにデプロイしています。各手順も公開しているコードを添えておきます。
npm install (yarn add)
npm install jsbarcode
説明するまでもなく、モジュールを使うときはたいていこれですね。yarnの人はyarn addです。
使用するcomponentでimport
import * as JsBarcode from 'jsbarcode';
https://github.com/nagamoto/demo/blob/master/src/app/barcode/barcode.component.ts#L3
Generate barcode on Angular2 project · Issue #134 · lindell/JsBarcode · GitHubを参考にimportしました。
バーコードを表示するためのhtml要素を用意
<svg id=fixedBarcode></svg>
https://github.com/nagamoto/demo/blob/master/src/app/barcode/barcode.component.html#L3
今回はsvg形式で表示するため、svgタグを定義しました。また、バーコードを設定する際にセレクタが必要なのでidを指定しています。
html要素にJsBarcodeを設定
JsBarcode('#fixedBarcode', 'fixedBarcode', {});
https://github.com/nagamoto/demo/blob/master/src/app/barcode/barcode.component.ts#L20
第1引数にバーコードを表示する要素を特定するためのセレクタを指定し、第2引数にバーコード化する値を指定します。 componentが初期化される際にバーコードが表示されて欲しいので、ngOnInitフックに記述しています。
軽くハマったポイント
- 動的ページ構築(*ngIfなど)でのNoElementException
- id属性の先頭が数字
動的ページ構築(*ngIfなど)でのNoElementException
アプリを作っていれば、必要なときだけ表示したりしなかったりするのは日常茶飯事です。Angularでは動的にページ要素を構築する場合に ngIf, ngFor, ngSwitchCase などを使います。こういった実装を行うと、タイミングによっては条件判定と要素の描画がなされていないためにJsBarcode('#fixedBarcode', 'fixedBarcode', {});実行時にセレクタに該当する要素がないという主旨の次のエラーが発生します。
NoElementException: No element to render on.
対策として、前述のエラーを避けるためにライフサイクル・フック*1を適切に使い分けました。安易によく使用するngOnInitを利用せず*2、適切なタイミングに設定しましょう。*3今回は*ngIfの判定が終わり、要素が描画されたタイミングです。そのためngAfterViewInitでバーコード描画処理を実行しています。
https://github.com/nagamoto/demo/blob/master/src/app/barcode/barcode.component.ts#L25
id属性の先頭が数字
id属性の先頭が数字だと、正常に動作しません。そもそも先頭が数字のid属性は認められていないので当然です。List構造で複数のUUID(のような値)をバーコードで表示する際に、バーコードを表示するhtml要素のid属性をユニークにするため次のようにUUIDを流用し、この問題に遭遇しました。
html例
<svg [id]="uuid" class="barcode"></svg>
ts例
JsBarcode(`#${this.uuid}`, this.uuid, {});
UUIDは数字を含むため、たまに数字が先頭の文字列になります。そのときのみエラーが発生します。先頭が数字のid属性は認められていないというのは初歩的な話ですがうっかりしていました。対策として適当なプリフィックスをつけて解決しました。当たり前ですがidは先頭が数字になる可能性がないか確認しましょう。
最後に
Angularはv8もリリースされ、とても便利なのでぜひ使ってみてください。私はv9でIvyが正式リリースされるのが楽しみです。
*1:https://angular.jp/guide/lifecycle-hooks
*2:自分に言い聞かせています
*3:Angularライフサイクル・フックの参考資料: https://qiita.com/tomonari-t/items/3fd6d3c30b6b007b0f14