【问题标题】:mxGraph and it's Types integration with angular 8mxGraph 及其与 Angular 8 的类型集成
【发布时间】:2020-03-12 22:10:10
【问题描述】:

当我使用任何 mxgraph 方法/值时,我的 mxgraph 是“未定义”

我已经在这个帖子上尝试过 viks 的回答:How to integrate mxGraph with Angular 4?

但即使这给了我打字和智能感知工作正常,我仍然有我的 mxgraph 未定义。

我应该提一下,这是一个全新的 Angular 项目,我只是按照 viks 的教程来到这里。

import { mxgraph } from "mxgraph";

declare var require: any;

const mx = require('mxgraph')({
  mxBasePath: 'assets/mxgraph'
});
@Component({...})
export class LetestComponent implements OnInit {
  ngOnInit() {
    var container = document.getElementById('graphContainer');
    var graph = new mx.mxGraph(container);
  }
}

在 HTML 文件中使用这个

<div id="graphContainer"></div>

我不应该有任何错误,我应该能够使用 mx 来调用任何 mxGraph 方法。

当我编译代码时,它似乎工作正常,但是当我在浏览器的控制台上查看它时,我有:

“未捕获的类型错误:无法设置未定义的属性 'mxBasePath' 在 build.js:11 在 Module../src/app/lettest/letest.component.ts (letest.component.ts:6)"

我不知道这是否是个问题,因为我使用的是 angular 8,而 viks 的答案是 angular 4,或者它是否是从那时起可能已经改变的打字稿语法。

如果有人可以帮助我,那就太棒了,

提前致谢!

编辑:我仍在尝试很多事情,但我认为我并不真正理解“require('mxgraph')”部分,即使 mx 常量不是未定义的,也存在未定义的部分如果我将它记录到课堂上的控制台。也许在 Angular 8 中有一种新方法可以做同样的事情?

我还应该提到 mxgraph 的类型似乎在 Visual Code Studio 中运行良好,就像我有定义但没有实际代码。

编辑 2:在深入研究之后,我开始使用 https://itnext.io/how-to-integrate-mxgraph-with-angular-6-18c3a2bb8566 但问题是这些类型已有 4 年历史,因此它缺少最新 mxgraph 版本中的大量方法/变量。

我发现在这些类型中只有(正在工作)

declare class mxGraph{..}

而最新的类型使用(不工作)

declare namespace mxgraph {
  export class mxGraph {..}
}

有人能解释一下区别吗?

【问题讨论】:

    标签: angular typescript mxgraph


    【解决方案1】:

    MxGraph 是一个用 JavaScript 编写的库。 Angular 使用的 TypeScript 具有类型(顾名思义),然后编译为 JavaScript(没有静态类型)。要让 TypeScript 了解 JS 库中的正确类型等,您需要一些类型定义。

    据我所知,MxGraph 不存在这样的类型定义。

    这不必阻止我们,我们仍然可以使用 JS 库!以下是我在项目中使用 MxGraph 的方式:

    我的package.json:"mxgraph": "^3.9.12", 有一个正常的依赖项

    但是我们还需要告诉 Angular 在哪里可以找到 JS-Script!看看我的 'angular.json' 文件:

    {
       "projects": {
          "architect": {
            "build": {
              "options": {
                  "assets": [
                        { "glob": "**/*", "input": "src/assets/", "output": "/assets/" },
                        { "glob": "favicon.png", "input": "src/", "output": "/" },
                        { "glob": "**/*", "input": "./node_modules/mxgraph/javascript/src", "output": "/assets/mxgraph" }
            ]
                  "scripts": [
                        "node_modules/mxgraph/javascript/mxClient.js"
                  ]}
            }
          }
        }
    }
    

    注意:我只包含了相关的部分。 我需要告诉 Angular 这个外部脚本应该包含在内并且可用。 See docs

    我的模板 (mygraph.component.html) 看起来有点不同:

    <div #graphContainer
         style="overflow:hidden;width:100%;height:100%; padding: 10px;">
    </div>
    

    你看,Angular 使用 '#' 符号作为模板引用!

    这是我的“mygraph.component.ts”:

    import 'mxgraph/javascript/mxClient.js';
    
    /**
    * externally (in mxClient) defined vars
    */
    declare var mxClient: any;
    declare var mxUtils: any;
    declare var mxRubberband: any;
    declare var mxConstants: any;
    declare var mxPerimeter: any;
    declare var mxEdgeStyle: any;
    
    const mx = require('mxgraph')({
        mxBasePath: 'assets/mxgraph'
    });
    
    @Component({
      selector: 'app-graph',
      templateUrl: './graph.component.html',
      styleUrls: ['./graph.component.scss']
    })
    export class GraphComponent {
    
      @ViewChild('graphContainer', { static: true }) graphContainer: Element;
    
      constructor(private http: HttpClient) {}
    
      // This I'm calling in my custom logic
      private draw() {
       // Checks if the browser is supported
        if (!mxClient.isBrowserSupported()) {
            mxUtils.error('Browser is not supported!', 200, false);
        } else {
            // Creates the graph inside the given container
            this.graphContainer['nativeElement'].innerHTML = '';
            const graph = new mx.mxGraph(this.graphContainer['nativeElement']);
    
            // Get and clone style, just for demonstration
            let style = graph.getStylesheet().getDefaultVertexStyle();
            let style2 = mxUtils.clone(style);
            graph.getStylesheet().putCellStyle('myStyle', style2);
    
            // Gets the default parent for inserting new cells. This
            // is normally the first child of the root (ie. layer 0).
            const defaultParent = graph.getDefaultParent();
    
            // Adds cells to the model in a single step
            graph.getModel().beginUpdate();
    
            try {
              // Do some drawing
              // graph.insertVertex(...
              // graph.insertEdge(...
            } finally {
              // Updates the display
              graph.getModel().endUpdate();
    
              // Make Graph not changeable by User
              graph.setEnabled(false);
            }            
        }
      }
    }
    

    虽然这不是一个完整的示例(我刚刚从我的代码中提取了一些有趣的部分),但它应该可以帮助您进行设置和开始。实际绘图请参考 MxGraph 文档。

    【讨论】:

    • 您好,感谢本杰明的回答!我也有你的方法,但问题是你有义务从 mxGraph 声明你想使用的任何东西,而且你在 IDE 上没有任何智能感知。这肯定是一种方法,如果我找不到解决方法,我可能最终会使用它!我还在这里找到了一些我们可以使用的不是 4 岁的类型定义:github.com/aleics/mxgraph-types 也在这里:github.com/lgleim/mxgraph-typings 但我也无法让它们正常工作。感谢您的回答:)!
    • @AnthonyD 我对最新的 mxgraph 版本进行了类型定义。 4.0.6。你可以在这里找到它。 npmjs.com/package/ts-mxgraph-typings
    【解决方案2】:

    我也找不到与此相关的任何资源。所以我自己做了几个npm包。你可以尝试在你的 Angular 项目中使用这些包之一。这些只是原始 mxgraph 库的 typescript 包装器。

    https://www.npmjs.com/package/ts-mxgraph

    https://www.npmjs.com/package/ts-mxgraph-factory

    https://www.npmjs.com/package/ts-mxgraph-typings

    我在我的项目中使用了以下方法。我在项目中创建了 mxgraph.overrides.ts 文件并导入了 mxgraph 原型。您还可以扩展库的原始方法。

    import '../../assets/deflate/base64.js'
    import '../../assets/deflate/pako.min.js';
    
    import { mxgraph, mxgraphFactory } from "ts-mxgraph";
    const mx = mxgraphFactory({
        mxBasePath: 'mxgraph',
        mxLoadResources: false,
        mxLoadStylesheets: false,
    });
    
    declare const Base64: any;
    declare const pako: any;
    
    let mxActor: any = mx.mxActor;
    let mxArrow: any = mx.mxArrow;
    let mxArrowConnector: any = mx.mxArrowConnector;
    let mxGraph: any = mx.mxGraph;
    let mxClient: any = mx.mxClient;
    let mxUtils: any = mx.mxUtils;
    ...
    // extends mxgraph prototypes
    mxGraph.prototype.updatePageBreaks = function(visible, width, height) {
    ...
    }
    // Adds panning for the grid with no page view and disabled scrollbars
    const mxGraphPanGraph = mxGraph.prototype.panGraph;
    mxGraph.prototype.panGraph = function(dx, dy) {
        mxGraphPanGraph.apply(this, arguments);
        ...
    }
    ...
    
    export {
        mxClient,
        mxUtils,
        mxGraph,
        ...
    }
    
    // and then import these where you want to use them
    
    import {
        mxClient,
        mxUtils,
        mxGraph,
        mxGraphModel,
        mxGeometry,
        mxConstants,
        mxCell,
        mxDictionary,
        mxCellEditor,
        mxStyleRegistry
    } from './mxgraph.overrides';
    
    import { IMAGE_PATH, STYLE_PATH, STENCIL_PATH, urlParams } from '../config';
    
    declare var Base64: any;
    declare var pako: any;
    
    export class Graph extends mxGraph {
    ...
    }
    

    【讨论】:

      猜你喜欢
      • 2023-04-02
      • 1970-01-01
      • 2020-08-19
      • 1970-01-01
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 2020-09-12
      • 1970-01-01
      相关资源
      最近更新 更多