edgesData.forEach不是Angular中的函数

问题描述 投票:1回答:1
import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
import { Network, DataSet, DataView} from 'vis';

@Component({
  selector: 'app-test',
  templateUrl: './test.component.html',
  styleUrls: ['./test.component.scss']

})
export class TestComponent implements AfterViewInit {
  @ViewChild('network', {static: false}) el: ElementRef;
  @ViewChild('nodeFilterSelect', {static:false}) nodeFilter: ElementRef;
  @ViewChild('edgesFilter', {static: false}) edgeFilter: ElementRef;
  private networkInstance: any;

  startNetwork(data){
    const container = this.el.nativeElement;
    this.networkInstance = new Network(container, data, {});
  }

  ngAfterViewInit() {
    const nodes = new DataSet<any>([
        { id: 1, label: 'Eric Cartman', age: 'kid', gender: 'male' },
        { id: 2, label: 'Stan Marsh', age: 'kid', gender: 'male' },
        { id: 3, label: 'Wendy Testaburger', age: 'kid', gender: 'female' },
        { id: 4, label: 'Mr Mackey', age: 'adult', gender: 'male' },
        { id: 5, label: 'Sharon Marsh', age: 'adult', gender: 'female' }
    ]);

    const edges = new DataSet<any>([
        { from: 1, to: 2, relation: 'friend', arrows: 'to, from', color: { color: 'red'} },
        { from: 1, to: 3, relation: 'friend', arrows: 'to, from', color: { color: 'red'} },
        { from: 2, to: 3, relation: 'friend', arrows: 'to, from', color: { color: 'red'} },
        { from: 5, to: 2, relation: 'parent', arrows: 'to', color: { color: 'green'} },
        { from: 4, to: 1, relation: 'teacher', arrows: 'to', color: { color: 'blue'} },
        { from: 4, to: 2, relation: 'teacher', arrows: 'to', color: { color: 'blue'} },
        { from: 4, to: 3, relation: 'teacher', arrows: 'to', color: { color: 'blue'} },
    ]);

    /**
     * filter values are updated in the outer scope.
     * in order to apply filters to new values, DataView.refresh() should be called
     */
    let nodeFilterValue = ''
    const edgesFilterValues = {
      friend: true,
      teacher: true,
      parent: true
    }

    /*
      filter function should return true or false
      based on whether item in DataView satisfies a given condition.
    */
    const nodesFilter = (node) => {
      if (nodeFilterValue === '') {
        return true
      }
      switch(nodeFilterValue) {
        case('kid'):
          return node.age === 'kid'
        case('adult'):
          return node.age === 'adult'
        case('male'):
          return node.gender === 'male'
        case('female'):
          return node.gender === 'female'
        default:
          return true
      }
    }

    const edgesFilter = (edge) => {
      return edgesFilterValues[edge.relation]
    }

    const nodesView = new DataView(nodes, {filter: nodesFilter})
    const edgesView = new DataView(edges, {filter: nodesFilter})


    this.nodeFilter.nativeElement.addEventListener('change', (e) => {
      // set new value to filter variable
      nodeFilterValue = e.target.value
      /*
        refresh DataView,
        so that its filter function is re-calculated with the new variable
      */
      nodesView.refresh()
    })

    const selectors = this.edgeFilter.nativeElement.querySelectorAll('label')
    console.log(selectors)
    selectors.forEach(filter => filter.addEventListener('change', (e) => {
      const { value, checked } = e.target
      edgesFilterValues[value] = checked
      edgesView.refresh()
    }))

    this.startNetwork({ nodes: nodesView, edges: edgesView })

  }
}

对于以上代码,我遇到一个错误,提示edgesData.forEach不是Angular中的函数。我认为此错误来自以下代码段:

    const selectors = this.edgeFilter.nativeElement.querySelectorAll('label')
    console.log(selectors)
    selectors.forEach(filter => filter.addEventListener('change', (e) => {
      const { value, checked } = e.target
      edgesFilterValues[value] = checked
      edgesView.refresh()
    }))

实际上,我要做的是将事件侦听器添加到我的三个输入值中。像这样的html:

<div>
    <label>
        Filter nodes
        <select #nodeFilterSelect>
          <option value=''>All characters</option>
          <option value='kid'>kids</option>
          <option value='adult'>adults</option>
          <option value='male'>male</option>
          <option value='female'>female</option>
        </select>
    </label>

    <br>
    <br>
    <label #edgesFilter>
      Filter edges
      <div>
        <label>
          <input type='checkbox'  value='parent' checked>
          Is <span style="color:green">parent</span> of
        </label>
      </div>
      <div>
        <label>
          <input type='checkbox' value='teacher' checked>
          Is <span style="color:blue">teacher</span> of
        </label>
      </div>
      <div>
        <label>
          <input type='checkbox' value='friend' checked>
          Is <span style="color:red">friend</span> of
        </label>
      </div>
    </label>
</div>

<div #network>

</div>

这里发生了什么,任何人都可以解释一下吗?我认为我以错误的方式使用了“ foreach”,我在Google上搜索了很多,但仍然对如何循环和添加侦听器感到困惑。

而且我也尝试使用for循环而不是foreach:

    const selectors = this.edgeFilter.nativeElement.querySelectorAll('input')
    for(const selector of selectors){
      console.log(selector)
      selector.forEach(filter => filter.addEventListener('change', (e) => {
        const { value, checked } = e.target
        edgesFilterValues[value] = checked
        edgesView.refresh()
      }))
    }

仍然出现错误说:

ERROR TypeError: selector.forEach is not a function
    at TestComponent.ngAfterViewInit (main.js:294)
    at callProviderLifecycles (vendor.js:64080)
    at callElementProvidersLifecycles (vendor.js:64045)
    at callLifecycleHooksChildrenFirst (vendor.js:64027)
    at checkAndUpdateView (vendor.js:74910)
    at callViewAction (vendor.js:75266)
    at execComponentViewsAction (vendor.js:75194)
    at checkAndUpdateView (vendor.js:74907)
    at callWithDebugContext (vendor.js:76241)
    at Object.debugCheckAndUpdateView [as checkAndUpdateView] (vendor.js:75823)

我只是意识到这是visjs的问题,我需要安装@ type / vis

javascript angular vis.js
1个回答
1
投票

您实际上是将事件添加到label元素,这将无法正常工作。更改事件适用于inputselecttextarea

我会说这对我来说似乎不是Angular的方式,但是也许我没有看到整个图片。我会做这样的事情,它只是控件和事件的一部分,

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  filterNodes = '';

  selectChange () {
    console.log(`filterNodes: ${this.filterNodes}`);
  }

  chkChange(evt) {
    const { value, checked } = evt.target;
    console.log(`${value}: ${checked}`);
  }
}
<div>
    <label>
        Filter nodes
        <select [(ngModel)]="filterNodes" 
        (change)="selectChange()">
          <option value=''>All characters</option>
          <option value='kid'>kids</option>
          <option value='adult'>adults</option>
          <option value='male'>male</option>
          <option value='female'>female</option>
        </select>
    </label>

    <br>
    <br>
    <label>
      Filter edges
      <div>
        <label>
          <input type='checkbox' value='parent' checked
          (change)="chkChange($event)">
          Is <span style="color:green">parent</span> of
        </label>
      </div>
      <div>
        <label>
          <input type='checkbox' value='teacher' checked
          (change)="chkChange($event)">
          Is <span style="color:blue">teacher</span> of
        </label>
      </div>
      <div>
        <label>
          <input type='checkbox' value='friend' checked
          (change)="chkChange($event)">
          Is <span style="color:red">friend</span> of
        </label>
      </div>
    </label>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.