以下の内容はhttps://ngmt83.hatenablog.com/entry/2019/06/12/084000より取得しました。


AngularアプリにJsBarcodeでバーコードを表示する

↓先日投稿した記事↓の続きです。 ngmt83.hatenablog.com

AngularでJsBarcodeというモジュールを使う方法を紹介します。

github.com

AngularからJsBarcodeを使用する方法(基本)

GitHub - lindell/JsBarcode: Barcode generation library written in JavaScript that works in both the browser and on Node.js

ここに書いてある通りで非常に簡単ですが、Angularに組み込むための手順があるので軽く説明します。

  1. npm install (yarn add)
  2. 使用するcomponentでimport
  3. バーコードを表示するためのhtml要素を用意
  4. html要素にJsBarcodeを設定

これだけです。簡単ですね。(なのにちょっとハマりました)

サンプルをこちらにデプロイしています。各手順も公開しているコードを添えておきます。

Demo

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




以上の内容はhttps://ngmt83.hatenablog.com/entry/2019/06/12/084000より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14