角度2 +中的事件传播

时间:2017-07-06 20:47:58

标签: javascript angular

我知道这个问题可能听起来很熟悉且重复,并且已经回答了很多次。请多多包涵。我发帖只是因为尽管尝试了其他问题中表达的解决方案,但我无法解决我的问题。

我在页面中有一个组件<od-resource-table [..] [..]></od-resource-table>呈现了2次。它基本上是一个表,并带有控件来显示/隐藏列。我面临的问题是,当我试图隐藏第二个表中的列时,它会影响第一个表而不是我想要的表。如果我删除第一个表,那么没有问题。请指教。我错过了什么,提前谢谢。

以下是发出的代码

  onChange(event: MouseEvent, field: string) {
        this.onToggleColumnVisibility.next(field)
        event.stopPropagation();
    }

这是展示行为的gif

http://g.recordit.co/AoKbazXdr2.gif

搜索控件组件包含列选择器控件

@Component({
    selector: 'od-search-control',
    templateUrl: './search-control.component.html',
    styleUrls: ['./search-control.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
    encapsulation: ViewEncapsulation.None
})
export class SearchControlComponent {
    @Input() searchText: string = '';
    @Input() searchPlaceholder: string = 'Search';
    @Input() downloadUrl: any = '';
    @Input() columnPickerDefs: Array<ISearchControl.ColumnPickerDef> = [];

    @Output() onRefresh = new EventEmitter<any>();
    @Output() onToggleColumnVisibility = new EventEmitter<any>();
    @Output() onTextChange = new EventEmitter<any>();

    constructor() { }

    onChange(event: MouseEvent, field: string) {
        event.stopPropagation();
        this.onToggleColumnVisibility.next(field)
    }
}

资源表组件

<div class="od-search-controls-bar">
      <div class="header">
        <h3>
          <span class="page-title">{{title}}</span>
          <span class="estimate">{{(estimate$ | async) | lpad : 2 : '0'}}</span>
        </h3>
        <div class="search-control-bar-wrapper">
            <od-search-control
            ...
            ...
            ...
            (onToggleColumnVisibility)="onToggleColumnVisibility($event)"

            ></od-search-control>
        </div>
      </div>
    </div>
    <od-data-table 
      #resTable
      [columnDefs]="columnDefs"
      [rowData]="rowData$ | async"
      [estimates]="estimate$ | async"
      [currentPage]="currentPage$ | async"
      [itemsPerPage]="itemsPerPage$ | async"
      (onPageChange)="onPageChange($event)"    
      (sortModel)="onSort($event)"
    ></od-data-table> 
@Component({
  selector: "od-resource-table",
  templateUrl: "./resource-table.component.html",
  styleUrls: ["./resource-table.component.scss"],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ResourceTableComponent implements OnInit, OnDestroy, OnChanges {
  @Input() category: string;
  ...
  ...
    onToggleColumnVisibility(columnField: string) {
    let columnIndex = this.columnDefs.findIndex(col => col.field === columnField);
    if (columnIndex > -1) {
      this.columnDefs[columnIndex].hide = !this.columnDefs[columnIndex].hide;
      this.columnDefs = [...this.columnDefs];
    }
  }

}

包含2个表的页面

@Component({

  selector: 'od-resource-assignment-view',
  template: `
   <div class="resource-navigation-panel">
      <label class="active"
          routerLink="/console-settings/resource-groups/"
      >Resource Groups</label>
      <label class="text-ellipsis"><span class="active">/</span>{{resourceGroupName}}</label>
    </div>
    <div class="assignment-resource-wrapper">
      <od-resource-table #assignedResourcesTable
        [resources]="(resourceGroupType$ | async)"
        [resourceGroupId]="resourceGroupId"
        [enableNodeSelection]="true"
        title="Assigned Resources"
        category="resource group">
      </od-resource-table>
      <div class="assign-button-wrapper">
        <button type="button" class="btn btn-secondary" (click)="unassignResources()">
          DEASSIGN
        </button>
      </div>
    </div>
    <div>
      <od-resource-table #enterpriseResourcesTable
        [resources]="(resourceGroupType$ | async)"
        [enableNodeSelection]="true"
        [exclude]="(excludeResources$ | async)"
        title="Total Resources"
        category="enterprise">
      </od-resource-table>
      <div class="assign-button-wrapper">
        <button type="button" class="btn btn-secondary" (click)="assignResources()">
          ASSIGN
        </button>
      </div>
    </div>
  `,
  styleUrls: ['./resource-assignment-view.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None
})
export class ResourcesAssignmentViewComponent implements OnInit, OnDestroy {
  @Input() resourceGroupId: string;
  @Input() resourceGroupName: string;
  @ViewChild('assignedResourcesTable') assignedResourcesTable: ResourceTableComponent
  @ViewChild('enterpriseResourcesTable') enterpriseResourcesTable: ResourceTableComponent
  resourceGroupType$: Observable<string>
  excludeResources$: Observable<string[]>
  resourceGroup: IResourceGroups.ResourceGroupItem
  _subs: Subscription[] = new Array<Subscription>()

  constructor(private _store: Store<IResourceGroups.ResourceGroupsState>) { }

  ngOnInit() {}
   ...
...
...

}

1 个答案:

答案 0 :(得分:0)

这是因为两个表都使用相同的onChange实例,当您执行操作时,第一个表首先接收事件,然后在侦听器中执行event.stopPropagation();

解决方案: 尝试区分侦听器中的表(onChange)或使用侦听器的单独实例。