複雑なWebプロジェクトをゼロから絶えず作成していると、コードの約3分の1(場合によっては半分以上)が実際に自律的であり、特定のDOM要素にのみ付加されていることに気づき始めます。
作業中のプロジェクトでは、次のようになります
function pageChange(){ if ($('.element-carousel').length>0) {$('.element-carousel').initCarousel()} if ($('.element-scrollbox').length>0) {$('.element-scrollbox').initScrollbox()} …
または、減らすことはできず、各条件付きコントローラー(特定のページを変更するためのコールバック)で、特定の要素に関連付けられたコードを呼び出します。
おなじみですか? そう思う。 このアプローチは間違っていると思いますか? 最初の答えが「はい」の場合、2番目の答えも「はい」であると確信しています。
正しく、きれいに、そして美しくできる方法を知りたいですか?
指令
AngularJSには、独自の機能であるディレクティブが記述されています。 しかし、今では彼女は本当にユニークではありません。
それらについての良い記事は
すでにハブにありました記事の内容全体を再語するのではなく、1つのフレーズのみを繰り返します。
ディレクティブを使用して、アプリケーションのモジュール性を高め、再利用を含むコンポーネントの個別の機能を強調することができます。
AngularJSディレクティブには、本質的に1つの大きなマイナス記号しかありません。AngularJSなしでは使用できません。独自の構造とマークアップでngアプリケーションを構築する必要があるという事実に直面しています。
したがって、4か月前に、同じ個別の要素固有のタスクを作成できるソリューションの開発が開始されました。
どのように機能しますか?
実装はMutationObserver(DOMツリーを変更するためのネイティブブラウザーイベント)で動作し、mutationイベント(DOMSubtreeModifiedなど)で動作するポリフィルを使用します。 他のすべてのデスクトップブラウザーがネイティブのMutationObserverを既にサポートしているため、PolyfillはIEにのみ本当に必要です。
残念ながら、ポリフィルでも、ネイティブブラウザのAndroid 2.3はサポートされていません。これは非常に残念ですが、4.0ではすべてのテストが安定して合格します。
理論的には、「マニュアル」-必要に応じて、更新ディレクティブを確認するための呼び出しで-IE6以降、ほとんどすべてのモバイルおよびデスクトップブラウザーでディレクティブのサポートが可能です。
開始する
構文は元々定義されていました:
directive('name', function(node){ alert("i'm alive!") })
最初はターゲット要素をthisにする必要がありましたが、多数のコールバック(その前にvar _this = thisを毎回書き込む必要があったため)を最初の引数に入れることにしました。
さらに、構文は別のオプションに拡張されました。
directive('name', { load: function(node){}, unload: function(node){} })
ロードイベントはディレクティブ(要素ではない)の外観に関連付けられ、アンロードはその削除に対応します。
なぜ指令の出現で正確になったのですか? なぜなら、それらは最初に登録することも、要素を操作する過程で追加および削除することもできるからです。 簡単な例-要素が次のように変更されると、このディレクティブが呼び出されます
<div class="container something">
に
<div class="container test something">
便利なこれ
したがって、コールバックは互いに値を渡すことができます-彼らは共通のこれを得ました。 したがって、これを行うことは非常に可能です。
directive('name', { load: function(){ this.interval = setInterval(function(){}, 1000) }, unload: function(){ clearInterval(this.interval) } })
場合によっては、コンテンツと対話するための外部メソッドを作成すると便利です。たとえば、移行の可能性があるプレゼンテーションです。 このため、スコープ自体が使用可能です-これはノードの属性の1つです。したがって、テストディレクティブの場合、これはnode.directiveTestになります。
その結果、ディレクティブのパブリックメソッドを作成することは簡単で便利になります。
directive('name', function(){ this.publicMethod = function(a){alert(a)} })
HTML構文
クラス、属性、およびタグはディレクティブのターゲットとして設定され、最初からプレフィックス「data-」を使用することが想定されていました(実際、コンフィギュレーターはデフォルトで別のプレフィックス「directive-」になります。これはディレクティブの読みやすさのために行われます。クラス:div class = "directive-scrollbox"は、div class = "scrollbox"よりもずっと明確です)。
したがって、このようなディレクティブは次のシナリオで実行されます。
<div class="name"/> <div class="data-name"/> <div name/> <div data-name="john"/> <name/> <data-name first-name="john" last-name="doe">
属性を操作する
属性からデータを転送する決定は、それ自体で要求されました。 属性のディレクティブの場合、ディレクティブタグの場合、属性値を送信するスクリプトが渡されました-オブジェクトはすべての属性から形成されます。 その結果、上記の例では、最初のケースでは「john」が渡され、2番目のケースでは{'first-name': 'john'、 'last-name': 'doe'}が渡されます。
より「スマートな」データ転送のために、「短い」オブジェクト構文のサポートが登場しました。name=“ first: 'john'、jast: 'doe'”と書くことができます。 実際、内部で起こるようなもの
try {value = eval( '{' + value + '}' )} try {value = eval( value )} return value
属性は変更される場合があり、属性を変更するための個別のコールバックがあります。
directive('name', { alter: function(){} }
場合によっては-たとえば、次のようなディレクティブの場合
directive('include', function(node, path){ $.get(path, function(data){node.innerHTML = data}) })
属性のロードと変更に関するアクションが繰り返されます。 したがって、ロード時のアクションが指定されていない場合、alterから自動的に実行され、生成されるコードの量を減らすことができます。
その結果、実行する必要がある要素固有のものから完全に抽象化できるツールを手に入れました。
例
一部のプロジェクトで既に使用されている大きなディレクティブのうち、最も快適なものの1つは
scrollboxで、これは要素にカスタムスクロールを掛ける要素の自動「ラッパー」です。
JsFiddleの例そして、ここに
ドラッグアンドドロップファイルを操作する簡単で便利
な方法があります 。 ファイルを灰色の四角にドラッグするだけです。
JsFiddleの例はい、コードは少しボリュームがありますが、jQueryを追加すると、約2倍短くなります。
ハブで数か月前に公開された開発者向けソリューションの繰り返しです。 ソリューションの魅力を感じるためには、Web開発パネルに入り、クローン要素の繰り返し値を手動で変更する必要があります。 属性を削除すると、要素は単一になり、その後属性を再度追加できます。
JsFiddleの例自分のプロジェクトでcornerJSを試してみたい人のために-縮小版と通常版はこちらです:
GitHubのCornerJSリポジトリ