7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AngularJS1.5の scope, bindingsで指定する @=&< の仕様を見直す

Last updated at Posted at 2016-03-23

AngularJS1.5 では、scope, bindings 指定時に @=& に加えて、< を指定できるようになった。< について追加で理解するとともに、=& を正しく理解していない側面があったため、まとめてみることにした。

$compile のドキュメントを参考にしました。

というわけでテスト書いて動作を試してみる。せっかくなので、AngularJS1.5から出たComponentを使う。

const app = angular.module('myApp', []);

class Widget {
  constructor() {
    this.name = 'Soba';
  }
  
  changeName() {
  	if (this.name == 'Soba') {
    	this.name = 'Udon';
    } else {
    	this.name = 'Soba';
    }
  }
}

app.component('widget', {
	template: '<div>Hello world, {{$ctrl.name}}</div>'+
  '<button ng-click="$ctrl.changeName()">Change Name</button>'+
  '<child-widget name-at="Hi, {{$ctrl.name}}" name-eq="$ctrl.name" name-gt="$ctrl.name"></child-widget>',
	controller: Widget
});

class ChildWidget {
	changeNameAt() {
  	this.nameAt = 'Yakisoba';
  }
  
  changeNameEq() {
  	this.nameEq = 'Yakisoba';
  }
  
  changeNameGt() {
  	this.nameGt = 'Yakisoba';
  }
}

app.component('childWidget', {
	controller: ChildWidget,
  template: '<div>@ {{$ctrl.nameAt}}</div>' + 
  '<div>= {{$ctrl.nameEq}}</div>' +
  '<div>&gt; {{$ctrl.nameGt}}</div>' + 
  '<button ng-click="$ctrl.changeNameAt()">Change nameAt</button>' +
  '<button ng-click="$ctrl.changeNameEq()">Change nameEq</button>' +
  '<button ng-click="$ctrl.changeNameGt()">Change nameGt</button>',
  bindings: {
  	'nameAt': '@',
    'nameEq': '=',
    'nameGt': '<'
  }
});

以下でテスト可能
https://jsfiddle.net/kawahara/we8k5x3f/4/

@

  • @ は、DOM属性に渡した情報が文字列として渡る
  • 内容については、HTMLと同じく $parse を通して解釈される。 name に Kawahara が入っていた場合 Hi, {{name}} とした時は、Hi, Kawahara が渡る。 name が別のものに変わった場合は別の文字に更新される。
  • $parse の必要のない固定の文字情報だったら、$attrs から情報取得したほうがいいのかな。

=

  • 双方向データバインディング
  • 親スコープからの変更は子スコープに伝搬され、子スコープの変更は親スコープに伝搬させる関係になる。

=?

  • 双方向なので、親スコープが情報なしの状態で、子スコープ側で変更が加わると、通常はエラーが発生するようになっている。? を指定すると、データを親から渡す挙動がオプションとなる。(エラーが抑制される。)

=*

  • 通常ではオブジェクトの変更トラッキングには、$watch を使っているが、 $watchCollection を使うような挙動に変わる。
  • 前述の ? と併用する場合は =?* のような書き方となる。
  • 正直、使いどころがよくわからん。。誰か教えて下さい。 https://teratail.com/questions/30528

<

  • 1.5から新しく追加された 単方向データバインディング (原文ではone-way bindingと記されている) と言われるもの。
  • 親スコープからの変更は子スコープに伝搬させるが、子スコープの変更は親スコープに伝搬させない特性を持っている。

<?

  • =? の単方向データバインディングバージョン。
  • ? 指定なし、親からのデータ渡しなしの状態で、子スコープの値を変更をしても、= のようにエラーはおきたりなどはしない。
  • コード見る限りは、余計な処理が走らなくなるので、親から値を渡さないことがあるのであれば、ぜひ指定しておくべき。

&

  • 子スコープには、&で指定した式を実行するための関数が渡る。
  • 実行可能な式を書けばいいので $ctrl.flag = true のような情報を渡す式を書いてもよい。
  • 親スコープ上で doSomething(data) を指定したときに、子スコープ上で doSomething({data: 'aaa'}) 実行すると、doSomething('aaa') が実行される。
7
7
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
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?