[解決済み】Angularのグローバルイベント
質問
に相当するものはないのでしょうか?
$scope.emit()
または
$scope.broadcast()
をAngularで使うか?
私は
EventEmitter
という機能がありますが、私の理解では、それは単に親HTML要素にイベントを発するだけです。
fx.の兄弟間や、DOMのルートにあるコンポーネントと数レベル深いネストにある要素との間で通信する必要がある場合はどうすればよいですか?
どのように解決するのですか?
に相当するものはありません。
$scope.emit()
または
$scope.broadcast()
をAngularJSから取得しました。
コンポーネント内のEventEmitterは近いですが、あなたが言ったように、それは直接の親コンポーネントにのみイベントを発行します。
Angularでは、他の選択肢もありますが、以下に説明したいと思います。
@Input()バインディングでは、アプリケーションモデルを有向オブジェクトグラフ(ルートからリーフへ)で接続することができます。コンポーネントの変更検出ストラテジーのデフォルトの動作は、接続された任意のコンポーネントからのすべてのバインディングに対して、アプリケーションモデルへのすべての変更を伝搬させることです。
余談ですが モデルには2種類あります。ビューモデルとアプリケーションモデルです。 アプリケーションモデルは、@Input()バインディングによって接続されます。ビューモデルは、コンポーネントのプロパティ(@Input()で装飾されていない)であり、コンポーネントのテンプレートにバインドされているだけです。
質問にお答えします。
兄弟コンポーネント間で通信する必要がある場合はどうすればよいですか?
-
共有アプリケーションモデル : 兄弟は共有アプリケーションモデルを介して通信することができます(ちょうどangular 1のような)。例えば、ある兄弟がモデルに変更を加えると、同じモデルへのバインディングを持つ他の兄弟が自動的に更新されます。
-
コンポーネントイベント : 子コンポーネントは、@Output()バインディングを使用して親コンポーネントにイベントを発行することができます。 親コンポーネントはそのイベントを処理し、アプリケーションモデルまたは自身のビューモデルを操作することができます。 アプリケーションモデルの変更は、同じモデルに直接または間接的にバインドしているすべてのコンポーネントに自動的に伝搬されます。
-
サービスイベント : コンポーネントは、サービスイベントを購読することができます。例えば、2つの兄弟コンポーネントが同じサービスイベントをサブスクライブし、それぞれのモデルを修正することによって応答することができます。詳細は後述します。
Rootコンポーネントと数レベルネストされたコンポーネントの間で通信するにはどうすればよいですか?
- アプリケーションモデルの共有 : アプリケーションモデルは、@Input()バインディングを通して、ルートコンポーネントから深くネストされたサブコンポーネントまで渡すことができます。任意のコンポーネントからのモデルへの変更は、同じモデルを共有するすべてのコンポーネントに自動的に伝搬されます。
-
サービスイベント
: また、EventEmitterを共有サービスに移動させ、任意のコンポーネントがサービスをインジェクトしてイベントを購読できるようにすることもできます。この方法では、ルートコンポーネントがサービスメソッド(通常はモデルの変更)を呼び出し、イベントを発生させることができる。 数層下の孫コンポーネントもサービスをインジェクトし、同じイベントをサブスクライブしているので、それを処理することができます。 共有されたアプリケーションモデルを変更するイベントハンドラは、それに依存するすべてのコンポーネントに自動的に伝搬されます。これはおそらく
$scope.broadcast()
Angular 1から採用されました。次のセクションでは、このアイデアをより詳細に説明します。
変更を伝えるためにサービスイベントを使用するObservableサービスの例
以下は、サービスイベントを使用して変更を伝達する、観測可能なサービスの例です。TodoItem が追加されると、サービスは、そのコンポーネントの購読者に通知するイベントを発行します。
export class TodoItem {
constructor(public name: string, public done: boolean) {
}
}
export class TodoService {
public itemAdded$: EventEmitter<TodoItem>;
private todoList: TodoItem[] = [];
constructor() {
this.itemAdded$ = new EventEmitter();
}
public list(): TodoItem[] {
return this.todoList;
}
public add(item: TodoItem): void {
this.todoList.push(item);
this.itemAdded$.emit(item);
}
}
以下は、ルートコンポーネントがイベントを購読する方法です。
export class RootComponent {
private addedItem: TodoItem;
constructor(todoService: TodoService) {
todoService.itemAdded$.subscribe(item => this.onItemAdded(item));
}
private onItemAdded(item: TodoItem): void {
// do something with added item
this.addedItem = item;
}
}
数レベルネストされた子コンポーネントも、同じようにイベントを購読します。
export class GrandChildComponent {
private addedItem: TodoItem;
constructor(todoService: TodoService) {
todoService.itemAdded$.subscribe(item => this.onItemAdded(item));
}
private onItemAdded(item: TodoItem): void {
// do something with added item
this.addedItem = item;
}
}
イベントをトリガーするサービスを呼び出すコンポーネントです(コンポーネントツリーのどこにあってもかまいません)。
@Component({
selector: 'todo-list',
template: `
<ul>
<li *ngFor="#item of model"> {{ item.name }}
</li>
</ul>
<br />
Add Item <input type="text" #txt /> <button (click)="add(txt.value); txt.value='';">Add</button>
`
})
export class TriggeringComponent{
private model: TodoItem[];
constructor(private todoService: TodoService) {
this.model = todoService.list();
}
add(value: string) {
this.todoService.add(new TodoItem(value, false));
}
}
参考 Angularの変更検出
関連
-
[解決済み】アンギュラーコンポーネントにサービスを注入しようとするとエラー "EXCEPTION: Can't resolve all parameters for component"、なぜ?
-
[解決済み] Angular 8 NgForはArray errorやAcces Control Allow originなどのIterableへのバインディングのみをサポートしています。
-
[解決済み] "rxjs" observable.throw は関数ではありません - Angular4
-
[解決済み] ローカルホストが私のアンギュラーアプリに対して無効な応答を送信しました。
-
[解決済み] Angular 6でmouseoverとmouseoutを使用する方法
-
[解決済み] jQuery 複数のイベントで同じ関数を起動する
-
[解決済み] Angular HTMLバインディング
-
[解決済み] Angular:*ngClassを使った条件付きクラス
-
[解決済み] モジュール "@angular-devkit/build-angular" が見つかりませんでした。
-
[解決済み] Angular2の括弧、括弧、アスタリスクの違いは何ですか?
最新
-
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 4アプリにReactiveFormsModuleを追加すると、NgControl用のプロバイダがないエラーが発生する。
-
[解決済み】ngサーブが機能しない
-
[解決済み] 型 '{}' は型 '{ title: string; text: string; }' に代入できません。
-
[解決済み] ng serve または firebase serve を終了させる方法
-
[解決済み] Angular CLIでピア依存をインストールする場合の対処方法は?
-
[解決済み] ローカルのワークスペース・ファイル('angular.json')が見つかりませんでした。しかし、同じコードが別のコンピュータで動作します
-
[解決済み] Angular2 Selectorが、ネストしたComponentのどの要素にもマッチしない。
-
[解決済み] このメソッドをリファクタリングして、認知的複雑度を21から許容される15に下げます。リファクタリングして複雑さを軽減する方法
-
[解決済み] モジュール 'ngx-cookie-service' が見つかりません。
-
[解決済み】Delegation: AngularのEventEmitterまたはObservable