AngularJS 1.5+ ComponentsはWatcherをサポートしませんが、どのように対処しますか?
質問
カスタムディレクティブを新しい
コンポーネントアーキテクチャにアップグレードしました。
. コンポーネントはウォッチャーをサポートしないと読みました。これは正しいのでしょうか?もしそうなら、どのようにオブジェクトの変更を検出するのでしょうか?基本的な例として、私はカスタムコンポーネント
myBox
これは、ゲーム上のバインディングを持つ子コンポーネントゲームを持っています。ゲームコンポーネント内の変更ゲームがある場合、どのように私はmyBox内のアラートメッセージを表示するには?私はrxJSのメソッドがあることを理解していますが、これを純粋にアンギュラーで行うことは可能ですか?私の
JSFiddle
JavaScript
var app = angular.module('myApp', []);
app.controller('mainCtrl', function($scope) {
$scope.name = "Tony Danza";
});
app.component("myBox", {
bindings: {},
controller: function($element) {
var myBox = this;
myBox.game = 'World Of warcraft';
//IF myBox.game changes, show alert message 'NAME CHANGE'
},
controllerAs: 'myBox',
templateUrl: "/template",
transclude: true
})
app.component("game", {
bindings: {game:'='},
controller: function($element) {
var game = this;
},
controllerAs: 'game',
templateUrl: "/template2"
})
HTML
<div ng-app="myApp" ng-controller="mainCtrl">
<script type="text/ng-template" id="/template">
<div style='width:40%;border:2px solid black;background-color:yellow'>
Your Favourite game is: {{myBox.game}}
<game game='myBox.game'></game>
</div>
</script>
<script type="text/ng-template" id="/template2">
<div>
</br>
Change Game
<textarea ng-model='game.game'></textarea>
</div>
</script>
Hi {{name}}
<my-box>
</my-box>
</div><!--end app-->
どのように解決するのですか?
のないコンポーネントの書き方 ウォッチャ
この回答では、AngularJS 1.5のコンポーネントを書く際に ウォッチャーを使用せずに
-
を使用します。
ng-change
ディレクティブ -
を使用します。
$onChanges
ライフサイクルフック -
を使用します。
$doCheck
ライフサイクルフック - とのコンポーネント間通信 require
- サービスから値をプッシュする RxJS
を使用します。
ng-change
ディレクティブ
AngularJs2の準備として、watchを使用せずにobjの状態変化を観察するために利用できるaltメソッドは何ですか?
を使うことができます。
ng-change
ディレクティブを使って、入力の変化に反応することができます。
<textarea ng-model='game.game'
ng-change="game.textChange(game.game)">
</textarea>
また、イベントを親コンポーネントに伝搬させるには、子コンポーネントの属性としてイベントハンドラを追加する必要があります。
<game game='myBox.game' game-change='myBox.gameChange($value)'></game>
JS
app.component("game", {
bindings: {game:'=',
gameChange: '&'},
controller: function() {
var game = this;
game.textChange = function (value) {
game.gameChange({$value: value});
});
},
controllerAs: 'game',
templateUrl: "/template2"
});
そして、親コンポーネントでは
myBox.gameChange = function(newValue) {
console.log(newValue);
});
これは今後望ましい方法です。AngularJSの戦略である
$watch
を使用する AngularJS の戦略は、ポーリング戦略であるため、スケーラブルではありません。なぜならポーリング戦略だからです。
$watch
リスナーの数が約2000に達すると、UIが重くなります。Angular 2の戦略は、フレームワークをよりリアクティブにし、$watch
の上に
$scope
.
を使用します。
$onChanges
ライフサイクルフック
と
バージョン 1.5.3
で、AngularJS は
$onChanges
ライフサイクルフックを
$compile
サービスにフックします。
Docsから。
コントローラは、ライフサイクルフックとして動作する以下のメソッドを提供することができます。
- $onChanges(changesObj) - 片方向の(
<
) または補間 (@
) のバインディングが更新されます。そのためchangesObj
はハッシュで、キーは変更されたバインドプロパティの名前、 値は以下の形式のオブジェクトです。{ currentValue: ..., previousValue: ... }
. このフックは、外側の値が誤って変更されるのを防ぐために、バインドされた値をクローンするなどのコンポーネント内の更新をトリガーするために使用します。- AngularJS Comprehensive Directive API リファレンス -- ライフサイクルフック
この
$onChanges
フックは、コンポーネントへの外部からの変更に反応するために
<
一方向バインディングで このフックは
ng-change
ディレクティブは
ng-model
ディレクティブを使用して、 コンポーネントの外側にある
&
バインディングを使用します。
を使用します。
$doCheck
ライフサイクルフック
と
バージョン 1.5.8
で、AngularJS は
$doCheck
ライフサイクルフックを
$compile
サービスにフックします。
Docsから。
コントローラは、ライフサイクルフックとして動作する以下のメソッドを提供することができます。
$doCheck()
- ダイジェストサイクルの各ターンで呼び出されます。変更を検出し、それに対応する機会を提供します。検出した変更に対応して取りたいアクションはすべてこのフックから呼び出されなければなりません; これを実装しても、いつ$onChanges
が呼び出されるタイミングには影響しません。例えば、このフックは、深い等式検査を行いたい場合や、Angularの変更検出器では検出されないDateオブジェクトの変更をチェックしたい場合などに有用です。$onChanges
. このフックは引数なしで呼び出されます。変更を検出する場合、現在の値と比較するために以前の値を保存する必要があります。- AngularJS Comprehensive Directive API リファレンス -- ライフサイクルフック
とのコンポーネント間通信
require
ディレクティブは を要求する ディレクティブは、他のディレクティブのコントローラを必要とし、 相互の通信を可能にします。これは、コンポーネント内で require プロパティにオブジェクトマッピングを提供することで実現できます。オブジェクトキーは、要求されたコントローラ (オブジェクトの値) が要求しているコンポーネントのコントローラにバインドされるプロパティ名を指定します。
app.component('myPane', {
transclude: true,
require: {
tabsCtrl: '^myTabs'
},
bindings: {
title: '@'
},
controller: function() {
this.$onInit = function() {
this.tabsCtrl.addPane(this);
console.log(this);
};
},
templateUrl: 'my-pane.html'
});
詳しくは AngularJS開発者ガイド - コンポーネント間通信
サービスから値をプッシュする RxJS
例えば、状態を保持しているサービスがある場合はどうでしょうか。そのサービスに変更を加え、ページ上の他のランダムなコンポーネントがそのような変更を認識できるようにするには、どうすればよいでしょうか。最近、この問題に取り組むのに苦労しています。
でサービスを構築します。 AngularのためのRxJS拡張機能 .
<script src="//unpkg.com/angular/angular.js"></script>
<script src="//unpkg.com/rx/dist/rx.all.js"></script>
<script src="//unpkg.com/rx-angular/dist/rx.angular.js"></script>
var app = angular.module('myApp', ['rx']);
app.factory("DataService", function(rx) {
var subject = new rx.Subject();
var data = "Initial";
return {
set: function set(d){
data = d;
subject.onNext(d);
},
get: function get() {
return data;
},
subscribe: function (o) {
return subject.subscribe(o);
}
};
});
そして、単純に変更を購読します。
app.controller('displayCtrl', function(DataService) {
var $ctrl = this;
$ctrl.data = DataService.get();
var subscription = DataService.subscribe(function onNext(d) {
$ctrl.data = d;
});
this.$onDestroy = function() {
subscription.dispose();
};
});
クライアントは変更点を
DataService.subscribe
で、プロデューサは
DataService.set
.
は PLNKRのDEMO .
関連
-
[解決済み] AngularJSのディープリンクとは何ですか?
-
[解決済み] Angular ng-repeatの条件付きラップアイテム(ng-repeatのグループアイテム)。
-
[解決済み] エラーです。10回の$digest()反復に達しました。動的なsortby述語で中断!?
-
[解決済み] AngularJSのリソースプロミス
-
[解決済み] AngularJS: ngRouteが動作しない。
-
[解決済み] ng-modelとng-bindの違いは何ですか?
-
[解決済み] ng-repeat :単一フィールドによるフィルタリング
-
[解決済み】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 UI-Routerのマルチビュー
-
[解決済み] ng-repeat内で$indexを使用して、クラスを有効にしてDIVを表示するにはどうすればよいですか?
-
[解決済み] エラーです。10回の$digest()反復に達しました。動的なsortby述語で中断!?
-
[解決済み] AngularJSのリソースプロミス
-
[解決済み] Angularjsを使用してローカルストレージにデータを保存するにはどうすればよいですか?
-
[解決済み] AngularJSとHandlebars - 両方必要なのかどうか
-
[解決済み] AngularJs .$setPristineでフォームをリセットする
-
[解決済み] Ui-srefがクリッカブルリンクを生成しない/動作しない
-
[解決済み] AngularJSを使用して、ブラウザのコンソールで$scope変数にアクセスするにはどうすればよいですか?
-
[解決済み] ServiceとFactoryで迷う