属性付きセレクタを作成する関数を作った。
属性付きセレクタを作成する関数を作った。
jqueryである属性がついたタグを取得したいと思ったときに、セレクタをハードコーディングすることがあります。
例えば以下のようなものです。
$("div[id='hoge']")
hoge
という値が動的に指定できる場合はもう少し面倒になります。
$("div[id='"+ val +"']")
たまに事故が起きるのは'
が抜けていたり、"
で囲えていなくてビルドがエラーになったりします。
今回はこういうことが無いように便利なutilを作りました。
Attrクラスを作成する
このクラスを使って属性指定します。
export class Attr { private key: string private val: string constructor(key: string, val: string) { this.key = key this.val = val } getKey() { return this.key } getVal() { return this.val } }
ちなみに、僕はconstructor
に引数が2つの場合はsetter
を作らないようにしてます。
3つ以上になったらsetter
を作成します。
属性付きセレクタを生成するためのutilを作成する
Attr
クラスをimport
しています。
今回はmakeAttrSelector
という関数を作りました。
import {Attr} from './Attr' export var SelectorUtils = { makeAttrSelector: function(target: string, attrs?: Array<Attr>) { if (attrs == void(0)) { return target } let selector = target + (function(attrs: Array<Attr>): string { let result = "" attrs.forEach((attr: Attr, index, array) => { result += "[" + attr.getKey() + "='" + attr.getVal() + "']" }) return result })(attrs) return selector } }
属性の指定がない場合にも対応可能なように、attrs
引数はオプションとしています。
このメソッドを実行すると以下のようになります。
let selector = SelectorUtils.tagAttrs( "#test", [new Attr("A", "A"), new Attr("B", "B")] ) console.debug(selector)
結果
#test[A='A'][B='B']
new Attr("A", "A")
が面倒に思えるかもしれません。
ただし、[{key: A, val: A}, {key: B, val: B}]
という方法に変えた場合、タイプミスが発生する可能性が高いです。
このような理由から今回はclass
を使いました。
テスト
便利なutil
を作成した場合は必ずテストを書きましょう。
多くの場所で使われることが想定できるので、誰かが修正した場合に品質を担保する必要があります。
今回はjest
を使用してテストを作成しました。
import {SelectorUtils} from '../SelectorUtils' import {Attr} from '../Attr' describe('test', () => { let idAttr = "#test" test.each([ [null, idAttr], [[new Attr("A", "A")], idAttr + "[A='A']"], [[new Attr("A", "A"), new Attr("B", "B")], idAttr + "[A='A'][B='B']"] ])("属性付きセレクタの生成テスト", (attrs, expected) => { let selector = SelectorUtils.tagAttrs(idAttr, attrs) console.log({ actual: selector, expected: expected, args: [attrs] }) expect(selector).toEqual(expected) }) test("attrs引数を指定しない場合", () => { let selector = SelectorUtils.tagAttrs("#test") expect(selector).toEqual("#test") }) });
テストにログを出すのはなぜかと聞かれたことがあります。
私の場合は以下の理由から出しています。
- テスト対象の関数が変更されたときにテストを修正しやすくするため