Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Directiveで実現できたこと

ng-mtg#6に登壇した際のスライド

  • Login to see the comments

Directiveで実現できたこと

  1. 1. Directiveで実現できたこと @konpyu 2014/07/25 ng-mtg#6
  2. 2. 自己紹介 • KON Yuichi (@konpyu)! • Software Engineer in peace of cake! • Server side engineer! • Love Angular
  3. 3. Agenda ・noteについて ・noteでのユースケース ・Directive Tips
  4. 4. 文章、音楽、イメージなどの コンテンツを作って発表
  5. 5. 簡単に販売できる 簡単に購入できる
  6. 6. マガジン ・ノートを束ねる機能
 ・雑誌のように編集
 ・カテゴリ機能として
 ・有料にもできる
  7. 7. 開発の規模感 • Rails 4.1 + nginx + MySQL + AngularJS(1.2系) • coffeeで8500Lくらい • 14 Controller, 33 Service, 36 Directive • エンジニア4名、デザイナー2名
  8. 8. Directive use case in note
  9. 9. 機能単位にコンポーネント化 DOM操作を要するもの
  10. 10. 機能単位にコンポーネント化 ・Controllerは極力薄く。Directiveに適切な$scope を与えることを中心事にする ・機能ごとにDirectiveに追い出す ・なるべくIsolate Directiveにする ・Isolateじゃなくても、ng-includeは使わずDirective にする
  11. 11. フォロー 数字が増える フォローする リンクが消える クリックすると…
  12. 12. フォロー html js userをisolate scopeで受け取る Clickイベントをbindする 成功したらフラグを立てる 見た目はng-classで切り替え イベントを発行。通知バーで表示反映
  13. 13. フォロー ユーザがフォローされた時の イベントを$scope.$onで受信し 表示を切り替え
  14. 14. スキ アイコンが追加される 星がつく クリックすると…
  15. 15. スキ noteをisolate scopeで受け取る Clickイベントをbindする OKならフラグを立てる & スキ一覧の配列にunshift
  16. 16. モーダル ui-bootstrapで提供されて いる$modalサービスを Directiveでラップ
  17. 17. モーダル Clickイベントで $modal.open()を呼ぶ Directiveのlink関数のscopeと$modalに渡す コントローラ内の$scopeが混じって危険なのが微妙
  18. 18. やってることはどれも大体同じ ・isolate scopeで変更対象のscopeを受け取る ・clickイベントにAPIをcallする処理を紐付ける ・表示の反映はng-classに適切な変数をbind ・必要に応じて$rootScope.$broadcastして更新通知
  19. 19. DOM操作を要するもの $(element)に対する処理をディレクティブに隠 して再利用できるようにしておく
  20. 20. Shift + Enterで改行するテキストエリア Enterを押すと送信されちゃう。Shift + Enterを押した
 時には改行にしたい
  21. 21. Shift + Enterで改行するテキストエリア
  22. 22. lazyload.jsをラップして遅延ロード
  23. 23. lazyload.jsをラップして遅延ロード imgタグの代わりにlazy-load-imageタグを使う
  24. 24. ・改行に応じて広がるテキストエリア ・表示と同時にフォーカスを当てる ・領域外の任意の位置をクリックすると消える通知 ・自動補完 他にも…
  25. 25. DOMを操作したくなったら Directiveの出番 ・Testablity / コンポーネント化 / 再利用性 ・ui-bootstrapのような外部ライブラリも検討 ・$watch内でDOM操作をすると激重になるので注意
  26. 26. Directive Tips
  27. 27. Directiveの親子関係 ・Directiveを入れ子にしたいとき ・子の中でrequire: 親のDirective名 を指定する ・linkの第四引数に親のcontrollerが入る ・親のcontrollerではやり取り用のAPIを用意
  28. 28. Directiveの親子関係 子のlinkの 第四引数に入る やり取り用のAPIを用意
  29. 29. ・Directiveの内部で起こった変更をどう他の ControllerやDirectiveに伝播させるか ! ・Angularアプリ全体の設計に関わる問題 それなりの規模のアプリを構築 すると必ずぶち当たる問題
  30. 30. ex) フォローボタンを押したら、通知欄の「xxxさんを フォローする」を消す
  31. 31. いまのnote $rootScope NavbarController $rootScopeからイベントを$broadcast 受信側は$scope.$onで受け取り処理を行う $scope.$on followUser (uid) -> # 表示の反映処理 Directive UserController # フォロー成功イベントを発行 $rootScope.$broadcast followUser , uid Directive
  32. 32. イベントベースの問題点 ・多用するとコードが追いにくくなる(なってる) ・2 way data bindingのメリットを捨てている
  33. 33. MainCtrlを置く方法 [参考] http://gon.to/2013/05/01/sharing-data-state-on- angularjs-alternatives-comparison-and-my-solution/ MainController UserController NavbarController Directive Directive scope: user: = Follow.save
 , (res) -> scope.user.is_follow = true scope: user: = $scope.obj.user = {} $scope.obj.user = { name: kon , is_follow: false} 2 way data bindingされて 自動的に表示変更
  34. 34. MainCtrlベース ・子のcontrollerは親のcontrollerのscopeにアクセスできる 性質を利用 ・MainCtrlにはbindingする変数定義のみ置く ・初期化は子のcontrollerで行う ・2 way data bind されるので$rootScope.$broadcast不要 ・MainCtrlの肥大化が懸念
  35. 35. 実際にあった悲劇 !?
  36. 36. 継承に関するDot Rule ・$scopeの継承の仕組みはjavascriptのprototype chainと 同じ($scope is pure javascript object) ・子の$scopeにhogeが無ければ、親の$scopeへhogeを探 しに行く ・hogeが文字列や整数のようなprimitiveな変数だと prototype chainが実行されない ・$scope.container.hoge のようにしてobjectを挟むとよい
  37. 37. まとめ Directiveを用いると ・共通部分を追い出して使いまわせる ・カプセル化 ・結果的にControllerを薄く出来る ・DOM操作がAngular wayに乗って行える
  38. 38. 参考資料 ! Directive to Directive Communication http://www.thinkster.io/angularjs/sMgLuIxf02/angularjs-directive-to-directive- communication ! PROPOSED ANGULAR S WEBPAGE STRUCTURE http://gon.to/2013/05/18/proposed-angulars-project-structure ! Nested Scopes in AngularJS http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html ! Combining AngularJS with existing Components http://henriquat.re/directives/advanced-directives-combining-angular-with- existing-components-and-jquery/angularAndJquery.html !
  39. 39. 参考資料 Rethinking AngularJS Controllers http://toddmotto.com/rethinking-angular-js-controllers/ ! Advanced Design Patterns and Best Practice http://trochette.github.io/Angular-Design-Patterns-Best-Practices/#/intro !

×