CoffeeScriptとAngularJS

Alexander Hill CoffeeScriptとAngularJSによる記事の翻訳。 これは私の最初の翻訳であり、コメントや訂正をお送りします。



CoffeeScriptはAngularJSコミュニティではあまり人気がありませんが、AngularJSとCoffeeScriptは素晴らしい組み合わせです。 この記事では、AngularJSコードを「簡単にする」いくつかのトリックを紹介します。



関数定義の短い記録



Angularは多数の匿名関数を使用するため、結果として、関数定義の短いレコードを使用することで多くの時間を節約できます。 例として、遅延してEnterキーを押すことにより式を評価する「キー入力」ディレクティブを作成してみましょう。 もちろん、このディレクティブは実用的な意味を持ちませんが、AngularJSとCoffeeScriptがどのように相互作用するかについてのアイデアを与える必要があります。

それでは、どのように使用しますか:

<input enter-key="submit()" enter-key-delay="10" />
      
      





JavaScriptコード:

 app.directive('enterKey', function ($timeout) { return function (scope, elem, attrs) { elem.bind('keydown', function (e) { if (e.keyCode === 13) { $timeout(function () { scope.$apply(attrs.enterKey); }, +attrs.enterKeyDelay); } }); } });
      
      





CoffeeScriptと比較してください:

 app.directive 'enterKey', ($timeout) -> (scope, elem, attrs) -> elem.bind 'keydown', (e) -> if e.keyCode is 13 $timeout -> scope.$apply attrs.enterKey , +attrs.enterKeyDelay
      
      





CoffeeScriptでは、シンボル->を使用して、関数の前に括弧で囲まれたパラメーターを定義します。 関数にパラメーターがない場合、角かっこは必要ありません。例は、$タイムアウトで渡される関数です。

10行のコードで関数キーワードを4回使用することは避けましたが、コードは読みやすくなり、コードを書く時間が短縮されました。 returnステートメントを使用する必要もありません。 CoffeeScript(Rubyなど)は、関数の最後の式の値を自動的に返します。



自動返品



自動(または暗黙的)リターンは、Angularコードの記述をより速く簡単にするもう1つの利点です。 以下は、自動復帰の有用性を確認できるいくつかの例です。 もちろん、違いはそれほど大きくありませんが、大規模なプロジェクトでは顕著です。



フィルター


 app.filter('capitalise', function (str) { return str.charAt(0).toUpperCase() + str.slice(1); });
      
      





 app.filter 'capitalise', (str) -> str.charAt(0) + str[1..]
      
      





この例のボーナスは、 str.slice(1)と配列の一部を取得するための構文です。 str [1 ..]



工場


 app.factory('urlify', function (text) { // nb:       return text.toLowerCase().replace(" ", ""); });
      
      





 app.factory 'urlify', (text) -> text.toLowerCase().replace " ", ""
      
      





ディレクティブ(再び)


この場合、オブジェクト定義ディレクティブを使用します。 CoffeeScriptの自動リターン、YAMLオブジェクトスタイルの構文、および関数定義の短いレコードを使用すると、コードがはるかに読みやすくなります。 次の例は、 AngularJSのドキュメントから引用したものです。

 app.directive('directiveName', function factory(injectables) { return { priority: 0, template: '<div></div>', templateUrl: 'directive.html', replace: false, transclude: false, restrict: 'A', scope: false, controller: function ($scope, $element, $attrs, $transclude, otherInjectables) { ... }, compile: function compile(tElement, tAttrs, transclude) { return { pre: function preLink(scope, iElement, iAttrs, controller) { ... }, post: function postLink(scope, iElement, iAttrs, controller) { ... } } }, link: function postLink(scope, iElement, iAttrs) { ... } } });
      
      





 app.directive 'directiveName', (injectables) -> priority: 0 template: '<div></div>' templateUrl: 'directive.html' replace: false transclude: false restrict: 'A' scope: false controller: ($scope, $element, $attrs, $transclude, otherInjectables) -> ... compile: (tElement, tAttrs, transclude) -> pre: (scope, iElement, iAttrs, controller) -> ... post: (scope, iElement, iAttrs, controller) -> ... link: (scope, iElement, iAttrs) -> ...
      
      





自動リターンとオブジェクト構文は、オブジェクト定義ディレクティブとコンパイル関数の両方で使用されます。



クラス


CoffeeScriptでは、クラスは言語機能に最も楽しいインクルージョンです。 それらは次のようになります。

 class Animal constructor: (@name) -> move: (meters) -> alert @name + " moved #{meters}m." snake = new Animal('snake') snake.move(10) # alerts "snake moved 10m."
      
      





CoffeeScriptでは、 @記号はこれの短い表記です。 したがって、 @ nameはthis.nameになります 。 さらに、 @記号を関数パラメーターに追加すると、Animalコンストラクターで見られるように、 これが自動的にthisに追加されます。

同様のJavaScriptコードの例を次に示します。 もちろん、 コンパイルされた CoffeeScriptコードと同一ではありませんが、機能的には同等です。

 function Animal(name) { this.name = name; } Animal.prototype.move = function (meters) { alert(this.name + "moved" + meters + "m.") } var snake = new Animal('snake') snake.move(10) // alerts "snake moved 10m.", as before
      
      





CoffeeScriptは名前付き関数を作成し、そのプロトタイプにメソッドを追加します。 Angularでは、これは2つの場合に役立ちます。サービス内と新しいController構文を使用する場合です。



サービス


ファクトリー関数は別の関数に直接追加されますが、サービスの場合、インスタンスは最初に作成されてから追加されます。 違いのより詳細な説明は、 この記事にあります。

サービスの例は、上記の記事から引用されています。

 var gandalf = angular.module('gandalf', []); function Gandalf() { this.color = 'grey'; } Gandalf.prototype.comeBack = function () { this.color = 'white'; } gandalf.service('gandalfService', Gandalf); var injector = angular.injector(['gandalf', 'ng']); injector.invoke(function (gandalfService) { console.log(gandalfService.color); gandalfService.comeBack() console.log(gandalfService.color); });
      
      





CoffeeScriptクラスからコンパイルされたJavaScriptコードのように見えます。 したがって、 プロトタイプ関数を直接編集する代わりに、CoffeeScriptクラスを使用できます。

 gandalf = angular.module 'gandalf', [] gandalf.service 'gandalfService', class Gandalf constructor: -> @color = 'grey' comeBack: -> @color = 'white' injector = angular.injector ['gandalf', 'ng'] injector.invoke (gandalfService) -> console.log gandalfService.color gandalfService.comeBack() console.log gandalfService.color
      
      





ここで、クラスをサービス関数に渡します。 サービスの前に定義してからサービスに転送することもできますが、クラスはサービスを通じてのみ使用できるようにしています。

依存関係の注入を示すために、 $タイムアウトサービスを使用して、遅延して「戻る」 ガンダルフを作成しましょう。

 gandalf.service 'gandalfService', class Gandalf constructor: (@$timeout) -> @color = 'grey' comeBack: (time) -> # ' '  coffeescript      #  'this',  @color -     ,   . @$timeout => @color = 'white' , time
      
      





引数の変数名は$ timeoutになるため、Angular依存性注入は引き続き機能します。 オブジェクトに依存関係を追加すると、たとえばcomeBackなどのメソッドでそれらにアクセスできます。



コントローラー


AngularJS 1.1.5では、新しいコントローラー構文が導入されています。 詳細についてはビデオを見ることができますが、基本的に新しい構文では、クラスをスコープ関数ではなくコントローラーとして渡すことができます。 したがって、AngularJSページのtodoListサンプルのhtmlコードは次のようになります。

 <body ng-app="todoApp"> <div ng-controller="TodoCtrl as todos"> <span>{{todos.remaining()}} of {{todos.list.length}} remaining</span> [<a href="" ng-click="todos.archive()">archive</a>] <ul> <li ng-repeat="todo in todos.list"> <input type="checkbox" ng-model="todo.done"> <span class="done-{{todo.done}}">{{todo.text}}</span> </li> </ul> <form ng-submit="todos.addTodo()"> <input type="text" ng-model="todos.input" placeholder="add a new todo"> <input type="submit" value="add"> </form> </div> </body>
      
      





このCoffeeScriptクラスをコントローラーとして使用します。

 app = angular.module 'todoApp', [] app.controller 'TodoCtrl', class TodoCtrl list: [ text: "learn coffescript" done: false , text: "learn angular" done: true ] addTodo: -> @list.push text: @input done: false @input = '' remaining: -> count = 0 for todo in @list count += if todo.done then 0 else 1 count archive: -> oldList = @list @list = [] for todo in oldList unless todo.done @list.push todo
      
      





おわりに



ご覧のとおり、CoffeeScriptはAngularJSの素晴らしい仲間です。 すべての人に適しているわけではありませんが、CoffeeScriptの録音のしやすさは欠点を上回っています。

この記事では言及しなかった他の便利な関数が数多くあります 。たとえば、 デフォルトパラメーター存在演算子配列、オブジェクトなどです 。 これにより、CoffeeScriptはプログラムを書くための快適で生産的な言語になります。 使用の可能性を考慮していない場合は、 公式Webサイトで詳細を確認してください。



All Articles