[英]sharing event driven variable across component in angular 2
I have a component which has a data table which I filter using a pipe, 我有一个包含数据表的组件,该数据表是使用管道过滤的,
The way I trigger and sent new argument to the pipe is on input-event on a input tag , I capture the input in 'targetInput' variable, 我触发并向管道发送新参数的方式是在input标签上的input-event上,我在'targetInput'变量中捕获输入,
The above setup works, here is how it looks like: 上面的设置有效,如下所示:
<tr >
<td *ngFor="let column of currentView.columns">
<div *ngIf="column.label">
<input placeholder="{{column.label}}" id="{{column._devName}}" type="text"
(input)="targetInput = {targetValue:$event.target.value,targetId:$event.target.id,currentFilterMap:currentFilterMap}">
</div>
</td>
</tr>
<ng-container *ngFor="let task of (currentView.tasks | countryPipe:targetInput); let i=index">
<tr class="worktask" (click)="setCurrentTask($event, task)" (dblclick)="openWindowNewTab(getOpenTaskURL(task, currentView.process))"
id="workspace_table_wo_{{ task.workOrderId }}_task_{{ task.taskId }}"
[class.table-active]="isSelected(task)">
<td *ngFor="let column of currentView.columns">{{task[column.devName]}}</td>
</tr>
Now I decide , that I want a separate component for the input tag , so I split the html and make a parent-child setup and pass the shared variable using @Input decorator, 现在,我决定要为input标签使用一个单独的组件,因此我拆分了html并进行了父子设置,并使用@Input装饰器传递了共享变量,
This is how the new setup looks , Parent html: 这是新设置的外观,父html:
<tr >
<td *ngFor="let column of currentView.columns">
<filterTagBox [taskCol] = "column" [currentFilterMap] = "currentFilterMap"></filterTagBox>
</td>
</tr>
<ng-container *ngFor="let task of (currentView.tasks | countryPipe:targetInput); let i=index">
<tr class="worktask" (click)="setCurrentTask($event, task)" (dblclick)="openWindowNewTab(getOpenTaskURL(task, currentView.process))"
id="workspace_table_wo_{{ task.workOrderId }}_task_{{ task.taskId }}"
[class.table-active]="isSelected(task)">
<td *ngFor="let column of currentView.columns">{{task[column.devName]}}</td>
</tr>
Now I can't seem to pass the targetInput from the child component back to the parent on the input event, Not sure if this is the way I should implement this or if there is a better way. 现在,我似乎无法在输入事件中将targetInput从子组件传递回父组件,不知道这是应该实现的方式还是有更好的方式。
I think in your case parent is Parent html and child is filterTagBox. 我认为在您的情况下,parent是Parent html,child是filterTagBox。 if you want transfer value from parent to child you need use @input
如果要将值从父母转移到孩子,则需要使用@input
if you want transfer value from child to parent you need use EventEmitter and @Output 如果要将值从子级转移到父级,则需要使用EventEmitter和@Output
more info. 更多信息。 https://angular.io/docs/ts/latest/cookbook/component-communication.html
https://angular.io/docs/ts/latest/cookbook/component-communication.html
I use BehaviorSubject
to notify any component (the parent in your situation) that subscribes it. 我使用
BehaviorSubject
通知任何订阅该组件的组件(您所处的父组件)。 It's a special type of observables. 这是一种特殊的可观察性。 A message service can do it for you.
消息服务可以为您做这件事。 Define a message model (you can even use a simple string if you prefer) and create a message service:
定义消息模型(如果愿意,甚至可以使用简单的字符串)并创建消息服务:
import {Observable, BehaviorSubject} from 'rxjs/Rx'; //
import {Message} from "../../models/message"; // Your model
... inside your message service class:
private _newMessage = new BehaviorSubject<Message>(new Message);
getMessage = this._currentUser.asObservable();
sendMessage(message: Message) { this._newMessage.next(message) }
In a component (eg in a parent), you can subscribe getMessage
subject like this: 在组件中(例如在父组件中),您可以订阅
getMessage
主题,如下所示:
this.messageService.getMessage.subscribe(
message => {
// a message received, do whatever you want
if (message == "so important message")
this.list = newList;
// ... so on
});
This way, multiple components can subscribe to this BehaviorSubject
, and any trigger in any component/service that uses sendMessage
method can change these subscribed components immediately. 这样,多个组件可以订阅此
BehaviorSubject
,并且任何使用sendMessage
方法的组件/服务中的任何触发器都可以立即更改这些订阅的组件。 For you, that can be a child component: 对您来说,这可以是子组件:
... you successfully made something in your
... child component, now use the trigger:
this.messageService.sendMessage(new Message("so important message", foo, bar));
Thanks for the answers , I did figure out how I could do this ,and although I found using behaviour service interesting I decided to use a output variable to sent data form the child component to the parent which would ultimatedly sent to the pipe, 感谢您的回答,我确实弄清楚了如何做到这一点,尽管我发现使用行为服务很有趣,但我还是决定使用输出变量将数据从子组件发送到父组件,最终将其发送到管道,
Here is what I did : 这是我所做的:
Child component HTML: 子组件HTML:
<div *ngIf="taskCol.label">
<div id="{{taskCol._devName}}_tagBox"></div>
<input placeholder="{{taskCol.label}}" id="{{taskCol._devName}}" type="text"
<!-- Call childComponent.onInput passing event parameters -->
(input)="onInput({targetValue:$event.target.value,targetId:$event.target.id})">
</div>
Child component.ts : 子component.ts:
@Component({
selector: 'filterTagBox',
template: require('./filterTagBox.component.html')
})
export class FilterTagBox{
private colValues:string[];
public containsQueries:boolean;
private regex:RegExp;
@Input() public taskCol:TaskColumn;
@Output() onItemInput = new EventEmitter<any>(); // bound event to the parent component
// constructor and other hidden methods...
onInput(targetInput : any){
this.onItemInput.emit(targetInput); //trigger onItemInput event on inputBox input
}
}
Parent component html : 父组件html:
<tr >
<td *ngFor="let column of currentView.columns">
<!-- Catch custom onItemInput event which was triggered in the child -->
<filterTagBox (onItemInput)="filterBoxPipeData = {targetValue:$event.targetValue,targetId:$event.targetId,currentFilterMap:currentFilterMap}" [taskCol] = "column" ></filterTagBox>
</td>
</tr>
<!--sent the data retrieve from the input i.e filterBoxPipeData to the pipe i.e tagBoxFilterPipe along with data to be filtered i.e currentView.task -->
<ng-container *ngFor="let task of (currentView.tasks | tagBoxFilterPipe:filterBoxPipeData); let i=index">
<tr>
<!--hidden html -->
</tr>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.