javascript - edgesData.forEach 不是 Angular 中的函数

标签 javascript angular vis.js

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”,我在谷歌上搜索了很多,但仍然对如何循环和添加监听器感到困惑。

我还尝试使用 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

最佳答案

您实际上是将事件添加到 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>

关于javascript - edgesData.forEach 不是 Angular 中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60461064/

相关文章:

javascript - 延迟加载模块基础模板

javascript - 字符串格式的 vis.js 轴值标签

javascript - 在我的 vis.js 堆叠条形图中,如何将标签移动到正确的位置?

javascript - jQuery 中的 Click() 没有执行任何操作

javascript - React 中如何区分不同的表单输入?

javascript - Node 文件传输在图像目录中上传 x 字节的图像,但已损坏

javascript - 如何使用 Browserify 指定自定义搜索路径?

Angular 6 : How to hide radio circle using Angular Material and use NgStyle for checked answer?

arrays - Angular ngFor 乱序

javascript - vis.js beforeAddNode 处理程序