LoginSignup
0
1

More than 5 years have passed since last update.

Angular2で`<foo checked>`を使う

Last updated at Posted at 2017-02-14

htmlの <input type="checkbox" checked>のような書き方ができます。
これは、「属性値の最小化(attribute minimization)」と呼ばれます。1

この記法は、XHTML(念のためにいうと、古い規格です)では使えず、<input checked="checked">と書く必要がありました。

やりたいこと

さて、Angular2でこのような独自属性を作りたいです。

<myComponent fixed> <!-- 空文字列''が来る -->
<myComponent fixed="true"> <!-- 文字列'true'が来る -->
<myComponent fixed="1"> <!-- 文字列'1'が来る -->

文字列がきちゃうんですよね。
TypeScript上では (this.isFiexed === true) とbooleanになってほしいです。

また、次のようなときにはfalseになって欲しいですよね。

<myComponent> <!-- 省略時はfalse -->
<myComponent fixed="false">
<myComponent fixed="-1">```

そんなboolean型な属性を書く方法です。

解決方法

方法1

@Inputを使いません。

import { Component, Attribute } from '@angular/core';


@Component({
  selector: 'myComponent',
  template: `
    <div> フィックス状態は {{isFixed}} です </div>
  `})
export class MyComponent { 

  isFixed;

  constructor(@Attribute("fixed") fixed) {
    this.isFixed = fixed !== 'false' && fixed !== '-1' && fixed !== undefined;
  }
}

比較的シンプルに書けますが、DIコードが沢山になりがちなconstructorが汚れること、値のバインディングができない点が欠点です。

方法2

@Input と setterのあわせ技です。

typescript
isFixed: boolean;

@Input("fixed") 
private set fixed(v: string){
   this.isFixed v !== 'false' && v !== '-1' && v !== undefined;
}

悪い方法

getterを定義してそれをバインドすると、数msごとにgetterが実行されちゃうので注意してください。

typescript
get isFixed(): boolean{
  console.log(' 何度も呼ばれるぞー ');
  return true;
}
<div *ngIf="isFixed">
  なんどもconsole.logからログが出てしまう
</div>

総評

そもそも、文字列でしかない属性値を無理にパースする処理なので、割り切って文字列として処理する、方法3のやり方が正しいのだと思います。


  1. 調べて初めて"attribute minimization"の呼び方を知ったけど、たぶん W3C-xhtml にもそう書いてあるから・・・あってるはず・・・。 

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1