angular.element対document.getElementByIdまたはスピン(ビジー)コントロール付きのjQueryセレクター


157

ここに記載されているように私は、スピンコントロールの「Angularised」バージョンを使用しています:http://blog.xvitcoder.com/adding-a-weel-progress-indicator-to-your-angularjs-application/

表示されたソリューションについて私が気に入らない点の1つは、スピンコントロールをDOM要素に効果的にアタッチするサービスでのjQueryの使用です。要素にアクセスするには、角度のある構造を使用したいと思います。また、スピナーがサービス内にアタッチする必要のある要素のIDを「ハードコーディング」するのを避け、代わりにサービス(シングルトン)でIDを設定するディレクティブを使用して、サービスの他のユーザーまたはサービス自体はそれを知る必要はありません。

私は、angular.elementが提供するものと、同じ要素IDのdocument.getElementByIdが提供するものとの間で苦労しています。例えば。これは機能します:

  var target = document.getElementById('appBusyIndicator');

これらのどれも行いません:

  var target = angular.element('#appBusyIndicator');
  var target = angular.element('appBusyIndicator');

私はかなり明白な間違いであるはずの何かをはっきりとやっています!誰か助けてもらえますか?

例えば:私は上記の作業を取得することができますと仮定すると、私は要素にjQueryのアクセスを交換しようとすると、同様の問題持って$(target).fadeIn('fast'); 作品を angular.element('#appBusyIndicator').fadeIn('fast')angular.element('appBusyIndicator').fadeIn('fast')いません

誰かがAngularの「要素」とDOM要素の使用を明確にするドキュメントの良い例を教えてもらえますか?Angularは明らかに独自のプロパティやメソッドなどで要素を「ラップ」しますが、元の値を取得することはしばしば困難です。たとえば、<input type='number'>フィールドがあり、ユーザーが「-」(引用符なし)を入力したときにUIに表示される元のコンテンツにアクセスしたい場合、何も表示されません。おそらく、「type = number」がAngularが拒否していることを意味するためUIに表示されていても入力を確認したいので、テストしてクリアします。

どんなポインタ/答えもありがたいです。

ありがとう。


5
angular.elementは、jQliteオブジェクトまたはjQueryをロードしている場合はjQueryオブジェクトです。
Neil

回答:


226

それそのように働くことができます

var myElement = angular.element( document.querySelector( '#some-id' ) );

Document.querySelector()ネイティブJavascript呼び出しを呼び出しにラップしangular.element()ます。したがって、利用可能/ロードされているかどうかに応じて、常にjqLit​​eまたはjQueryオブジェクトの要素を取得しますjQuery

の公式ドキュメントangular.element

jQueryが使用可能な場合、angular.elementjQuery関数のエイリアスです。jQueryのを使用できない場合は、angular.elementに委譲角度 Sは、内蔵のサブセットjQuery、「jQueryのライト」またはと呼ばれることjqLit​​e

内のすべての要素参照はAngular、常にjQueryまたはjqLite(ディレクティブコンパイルまたはリンク関数の要素引数など)でラップされます。それらは決して生のDOM参照ではありません。

なぜ使用するのか疑問に思われる場合はdocument.querySelector()この回答をお読みください。


41
単にdocument.getElementById()を使用するよりもdocument.querySelector( '#...')を好む理由は何ですか?
加藤

4
これは、角度要素でも実行できます。varelDivParent = angular.element(elem [0] .querySelector( '#an-id'));、 elemは角度要素です。このようにして、要素内を検索できます。単体テストに役立ちます。
unludo 2014年

4
@Kato この回答の詳細情報。お役に立てば幸いです。
カイザー

Google Maps APIを使用して、これは機能しました:var autocomplete = new google.maps.places.Autocomplete( $document[0].querySelector('#address'), { types: ['geocode'], componentRestrictions: {country: 'us'} } );。ヒント@kaiserをありがとう。何らかの理由で、maps apiは、最初のパラメーターで渡したものはを使用したときの入力ではなかったと報告しましたangular.element(document.querySelector('#address'))が、すべてうまくいきました。
nymo

49

まだ読んでいない場合は、角度要素のドキュメントを読んでください。jqLit​​eでサポートされているものと、-jqliteでサポートされていないものは、angularに組み込まれているjqueryのサブセットです。

IDによるセレクターはサポートされていないため、これらのセレクター jqLit​​eだけでは機能しません。

  var target = angular.element('#appBusyIndicator');
  var target = angular.element('appBusyIndicator');

だから、どちらか:

  • jqueryよりも制限されたjqLit​​eを単独で使用しますが、ほとんどの状況で十分です。
  • または、アプリに完全なjQuery libを含めて、jqueryが本当に必要な場所で、通常のjqueryのように使用します。

編集:jQueryは、jqLit​​eよりも優先するために、angularJSのにロードする必要があることに注意してください。

DOMContentLoadedイベントが発生する前に読み込まれた場合、実際のjQueryは常にjqLit​​eよりも優先されます。

Edit2:前に質問の2番目の部分を逃しました:

問題は<input type="number">、私は考えてそれはの意図した動作であり、それは角度の問題ではありませんネイティブ HTML5の数要素。

jquery .val()またはraw .value属性で値を取得しようとしても、数値以外の値は返されません。


2
完全なjQueryライブラリがあります-そうしないと、上記で説明した$シナリオが機能しません。私の質問は、なぜ$は機能するが、angular.elementは機能しないのかということでした-完全なjQueryが利用可能であっても。
イラクの2013年

1
angular.jsの前または後にjQueryを含めていますか?角度を付けるに含める必要があります。IDによるセレクタはやる:jQueryを利用できるとの仕事jsbin.com/ohumiy/1/edit
garst

1
それらは別のディレクティブ(つまり、IDで何かにアクセスするangular.element)で動作しています。問題は、このコントロールをその要素にアタッチすることでこのコントロールが機能する方法にあるようですが、同じjQueryの同等物が直接機能する理由がわかりません。jQueryを直接使用すると、私のディレクティブは終了タグを持つ必要があります-自己終了タグは機能せず(空白の画面だけでエラーは発生しません)、コントロールが疑われます。
irascian 2013年

2
2番目のポイントには、要素のコンテンツを取得するために使用できるview $ valueのようなものもありますが、ユーザーが「-」と入力したinput type = numberの場合、これは空です。要素のプログラムでアクセスできない場合でも「-」がまだUIにあるため、Angularが介入する前に要素の$ rawInputValueなどのプロパティにコンテンツを表示させたいのですが。
irascian 2013年

27
var target = document.getElementById('appBusyIndicator');

等しい

var target = $document[0].getElementById('appBusyIndicator');

1
2番目の例を使用して、依存関係が明示的であり、モックできることを確認する方がよいでしょう。
ルーク、

それはそうであるべきですが、私はangular 2+ではtypescript機能にもっと依存していると思います。これらのことについて心配する必要はもうありません:)
Dasun

17

Angularを使用するのは正しい方法ではないと思います。フレームワークメソッドが存在しない場合は、作成しないでください。これは、フレームワーク(ここでは角張った)がこのように機能しないことを意味します。

angularでは、このようにDOMを操作するべきではありません(jqueryの方法)。ただし、次のような角度ヘルパーを使用してください。

<div ng-show="isLoading" class="loader"></div>

または、独自のディレクティブ(独自のDOMコンポーネント)を作成して、それを完全に制御します。

ところで、あなたはここで見ることができますhttp://caniuse.com/#search=queryselector querySelectorはよくサポートされているので安全に使用できます。


2
あなたは絶対的に正しいです。DOMを手動で操作する必要があると思ったケースの90%以上で、コードをリファクタリングして必要性を取り除き、最終的にコードははるかにクリーンになりました。
スティーブンチョン

17

gulpを使用document.getElementById()している場合、使用するとエラーが表示され、使用するように提案されます$document.getElementById()が、機能しません。

使用する -

$document[0].getElementById('id')

ここでなぜ配列を角度注入するのですか?
ピーター

16

$ documentを使用して要素にアクセスできます($ documentを挿入する必要があります)

var target = $document('#appBusyIndicator');
var target = $document('appBusyIndicator');

または角度要素を使用すると、指定した要素には次のようにアクセスできます。

var targets = angular.element(document).find('div'); //array of all div
var targets = angular.element(document).find('p');
var target = angular.element(document).find('#appBusyIndicator');

1
find()-タグ名によるルックアップに限定
RJV

angular.element(document).find( '。someClass'); 完璧に動作します。
Nishant Baranwal 2017

10

$ documentをコントローラーに挿入し、元のドキュメントオブジェクトの代わりに使用する必要があります。

var myElement = angular.element($document[0].querySelector('#MyID'))

jqueryスタイル要素のラップが必要ない場合、$ document [0] .querySelector( '#MyID')はDOMオブジェクトを提供します。


1
Angulars $ documentサービスのオーバーヘッドを使用する代わりに、window.documentを直接参照することもできます。
MatBee 2015年

5
もちろん、単体テストで$ documentをモックすることを心配しなくてもできます
Adamy

私にはわかりません:この警告が表示されます:デフォルトのドキュメントオブジェクトの代わりに$ documentサービスを使用する必要がありますが、それはどういう意味ですか?それについてのドキュメントはありますか?ありがとう!
realnot

@realnot JavaScriptのどこからでもHTML DOM Document Objectにアクセスできます。w3schools.com/jsref/dom_obj_document.asp
アダミー

6

これでうまくいきました。

angular.forEach(element.find('div'), function(node)
{
  if(node.id == 'someid'){
    //do something
  }
  if(node.className == 'someclass'){
    //do something
  }
});

3
要素は未定義ですか?angular.element.findは、jQueryなしであなたが試してみる関数ではありません。
着陸

3
これを行わないでください。他の例のいずれかを使用します。これはハッシュテーブルルックアップの最適化をまったく使用しません。
MatBee 2015年

4

カイザーの答えの改善:

var myEl = $document.find('#some-id');

$documentディレクティブに注入することを忘れないでください


21
element.find:の角度に関するドキュメントで述べたように、find() - Limited to lookups by tag nameidでは機能しません。また、あなたは余分な終わりを持っています)
paaat

3

多分私はここでは遅すぎるかもしれませんが、これはうまくいきます:

var target = angular.element(appBusyIndicator);

ありませんappBusyIndicator。これはプレーンID値です。

舞台裏で何が起こっているのか:(divに適用されていると仮定して)(angular.js行番号から取得:2769以降...)

/////////////////////////////////////////////
function JQLite(element) {     //element = div#appBusyIndicator
  if (element instanceof JQLite) {
    return element;
  }

  var argIsString;

  if (isString(element)) {
    element = trim(element);
    argIsString = true;
  }
  if (!(this instanceof JQLite)) {
    if (argIsString && element.charAt(0) != '<') {
      throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
    }
    return new JQLite(element);
  }

デフォルトでは、ページにjQueryがない場合、jqLit​​eが使用されます。引数は内部的にIDとして認識され、対応するjQueryオブジェクトが返されます。


私は今、Angular 1.5.8でこれを試しました。プレーンIDは空の結果を返します。angular.element("#myId")うまくいきます。
Gosha U.

多分あなたはあなたのページにjQueryを持っていますか?
Vishal Anand、2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.