[解決済み] AngularJSのng-repeatスコープを使ったディレクティブアイソレートスコープ
質問
分離スコープを持つディレクティブ (そのディレクティブを他の場所で再利用できるようにするため) がありますが、このディレクティブを
ng-repeat
で使用すると、動作しません。
私はこのトピックに関するすべてのドキュメントとStack Overflowの回答を読み、問題点を理解しました。私は、通常のゴチャをすべて回避できたと信じています。
で作成されたスコープが原因で私のコードが失敗することを理解しました。
ng-repeat
ディレクティブによって作られるスコープが原因で失敗するのだと理解しています。私のディレクティブは孤立したスコープを作り、親スコープにあるオブジェクトに双方向のデータバインディングを行います。私のディレクティブはこのバインドされた変数に新しいオブジェクトの値を割り当てます。
ng-repeat
を使用しない場合、これは完全に動作します (親変数は正しく更新されます)。しかし
ng-repeat
では、代入は新しい変数を作成します。
ng-repeat
スコープに新しい変数が作成され、親変数はその変更を認識しません。これはすべて、私が読んだことに基づくと予想されることです。
また、与えられた要素に複数のディレクティブがある場合、1 つのスコープのみが作成されることも読みました。そして
priority
を各ディレクティブに設定することで、 ディレクティブの適用順序を定義することができます。 ディレクティブは優先度でソートされ、そのコンパイル関数が呼ばれます (優先度という単語で検索すると
http://docs.angularjs.org/guide/directive
).
そこで、優先順位を使って、私のディレクティブが最初に実行され、isolate-scope を作成することになるようにできればと思ったのですが、そのときに
ng-repeat
が実行されたとき、プロトタイプ的に親スコープを継承するスコープを作成する代わりに、孤立したスコープを再利用します。そのため
ng-repeat
のドキュメントによると、このディレクティブは優先度
1000
. しかし
1
が高い優先度なのか低い優先度なのかが不明です。優先レベルを使用した場合
1
を使っても違いが出なかったので、試しに
2000
. しかし、これは事態を悪化させます。私の双方向バインディングは
undefined
になり、ディレクティブは何も表示されません。
私は
を作成しました。
. をコメントアウトしました。
priority
をコメントアウトしています。私は名前オブジェクトのリストと
name-row
というディレクティブがあり、name オブジェクトの姓と名のフィールドを表示しています。表示された名前がクリックされたとき、その名前に対して
selected
変数をセットするようにしたい。名前の配列である
selected
変数に渡されます。
name-row
ディレクティブに渡されます。
私は、メインスコープで関数を呼び出すことによって、これを動作させる方法を知っています。また、もし
selected
が別のオブジェクトの内部にあり、外側のオブジェクトにバインドすれば、うまくいくことも知っています。しかし、私は今のところ、それらの解決策に興味がありません。
その代わりに、私が持っている疑問は
-
どのようにすれば
ng-repeat
が親スコープをプロトタイプ的に継承するスコープを作るのを防ぎ、 代わりに私のディレクティブの isolate-scope を使うようにするにはどうしたらよいでしょうか? -
なぜ優先順位が
2000
が機能しないのでしょうか? - Batarangを使用して、使用中のスコープの種類を知ることは可能ですか?
どのように解決するのですか?
さて、上記の多くのコメントを通じて、私は混乱を発見しました。まず、いくつかの点を明確にします。
- ngRepeat は選択した分離スコープに影響を与えません。
- ディレクティブの属性で使用するために ngRepeat に渡されるパラメータです。 を行います。 プロトタイプに継承されたスコープを使用する
- ディレクティブが動作しない理由は、分離されたスコープとは関係ありません。
同じコードで、ディレクティブを削除した例です。
<li ng-repeat="name in names"
ng-class="{ active: $index == selected }"
ng-click="selected = $index">
{{$index}}: {{name.first}} {{name.last}}
</li>
ここでは JSFiddle で、これが動作しないことを示します。あなたのディレクティブと全く同じ結果を得ることができます。
なぜうまくいかないのでしょうか?AngularJSのスコープはプロトタイプの継承を使用しているからです。値
selected
を親スコープに置くと
プリミティブ
. JavaScriptでは、子プロセスが同じ値を設定すると上書きされることを意味します。AngularJSのスコープには黄金律があります:モデルの値は
常に
を持つことです。
.
を含む。つまり、これらは決してプリミティブであってはならないのです。参照
このSOの答え
を参照してください。
スコープが初期状態でどのようなものかを示す画像です。
最初の項目をクリックすると、スコープが次のようになりました。
新しい
selected
プロパティが ngRepeat スコープに作成されたことに注意してください。 コントローラスコープ003は変更されていません。
2番目の項目をクリックすると何が起こるか、おそらく想像がつくでしょう。
つまり、あなたの問題は実はngRepeatが原因ではなく、AngularJSの黄金律を破っていることが原因なのです。それを解決する方法は、単にオブジェクトプロパティを使用することです。
$scope.state = { selected: undefined };
<li ng-repeat="name in names"
ng-class="{ active: $index == state.selected }"
ng-click="state.selected = $index">
{{$index}}: {{name.first}} {{name.last}}
</li>
ここでは 第二のJSFiddle で、これも動作することがわかります。
初期状態では以下のようなスコープになっています。
最初の項目をクリックした後
ここでは、希望通り、コントローラスコープに影響を及ぼしています。
また、これが分離されたスコープを持つディレクティブでも動作することを証明するために (繰り返しますが、これはあなたの問題とは関係ありませんから)、 ここでは JSFiddle をご覧ください。これも、ビューにオブジェクトが反映されていなければなりません。必要な唯一の変更は オブジェクトを使用することです。 の代わりに プリミティブ .
最初はスコープ。
最初の項目をクリックした後のスコープ。
結論から言うと、もう一度言いますが、あなたの問題はisolateスコープやngRepeatの動作方法に関するものではありません。あなたの問題は、まさにこの問題を引き起こすことが知られているルールを破っていることです。AngularJSのモデルには、常に
.
.
関連
-
[解決済み] AngularJsでng-Cloakディレクティブを実際に使用する方法とは?
-
[解決済み] AngularJSの「href」と「ng-href」の違いについて
-
[解決済み] 新しい/分離されたスコープを求める複数のディレクティブ [ngController, ...] がある。
-
[解決済み] AngularJSを使用して、ブラウザのコンソールで$scope変数にアクセスするにはどうすればよいですか?
-
[解決済み] AngularJSで$scope.$watchと$scope.$applyを使用するにはどうすればよいですか?
-
[解決済み] AngularJS コントローラにおける 'this' と $scope の比較
-
[解決済み】AngularJSのディレクティブスコープにおける「@」と「=」の違いは何ですか?
-
[解決済み】AngularJSのスコーププロトタイピング/プロトタイピング継承のニュアンスとは?
-
[解決済み] AngularJSで独自のスコープ*を持つカスタムディレクティブ内から親スコープにアクセスするにはどうすればよいですか?
-
[解決済み】AngularJSでディレクティブを書くとき、新しいスコープ、新しい子スコープ、または新しい分離されたスコープが必要であるかどうかは、どのように決定するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 適用がすでに進行中のエラー
-
[解決済み] Angular JS $locationChangeStart 次の url ルートオブジェクトを取得する
-
AngularJS がエラー $digest already in progress を報告する
-
angularjsのルーティングについて $stateと$stateParamsの話
-
[解決済み] ngInject'を本当に書く必要があるのか?
-
[解決済み] AngularJSの.$on()とは?
-
[解決済み] AngularJSのng-repeatでキーと値を反復処理する方法は?
-
[解決済み] 条件に応じて特定のルートにリダイレクトする機能
-
[解決済み】AngularJSのスコーププロトタイピング/プロトタイピング継承のニュアンスとは?
-
[解決済み】AngularJSでディレクティブを書くとき、新しいスコープ、新しい子スコープ、または新しい分離されたスコープが必要であるかどうかは、どのように決定するのですか?