如何防止更改链接或元素?

时间:2018-01-09 17:25:02

标签: javascript element onchange restriction jointjs

我需要限制某些链接和元素的用户交互。 例如,如果用户移动或删除项目,则此项目的最后状态将立即显示,图表似乎不会改变。

理想情况下,我正在寻找一个简单的属性,可以在创建元素时添加该属性,以防止所有更改发生,例如isModifiable: false

由于我找不到,我使用change事件和一个不太优雅的链接递归解决方案(作为下面的答案添加,现在已编辑用另一种更好的解决方案)。

是否存在停止或限制更改发生的理想方法?

2 个答案:

答案 0 :(得分:2)

您应该阻止用户在论文中执行操作,而不是阻止程序员对图表进行更改。

请参阅interactive option dia.Paper

// add the specific attribute to your desired shape
link.set('isModifiable', true);

// use the `interactive` option within your paper
new joint.dia.Paper({
  interactive: function(cellView) {
    return cellView.model.get('isModifiable');   
  }
});

请注意,通过这种方式,您仍然可以通过编程方式更改链接。

// this will trigger `change` event, but it won't be reverted
link.attr('.connection/stroke', 'red');

答案 1 :(得分:1)

个人Element / Link限制

我设法通过修改与细胞相关的事件来部分解决这个问题,例如joint.dia.Link

  1. change事件添加自定义功能;
  2. 触发更改后,从图表中删除新更改的链接;
  3. 使用初始链接的完整克隆并再次克隆,以将其用作新恢复的链接;
  4. 将相同的功能添加到克隆的链接change事件;
  5. 将克隆的链接添加到图表中。
  6. 所以这些将是:

    let mylink = new joint.dia.Link({
      source: sourceObj,
      target: targetObj,
      attrs : attrsObj
    });
    let mylinkClone = mylink.clone();
    
    function restoreLink(link, changeStats) {
      link.remove();
      let rlink = mylinkClone.clone();
      rlink.on('change', restoreLink);
      rlink.addTo(graph);
    }
    
    mylink.on('change', restoreLink);
    

    一旦用户点击删除按钮,或尝试拖出链接或其他任何内容,就没有视觉上的变化。

    这可能不是一个非常优雅或高性能的解决方案(由于重复克隆),我注意到在token is sent through the link期间,用户仍然可以删除它。但是,如果你创建了一个非常具体的链接/元素,你需要限制它,它仍然有效。

    纸张interactive属性限制

    这是使用joint.Paper.prototype.options.interactive suggested by Roman in another answer限制对论文中所有元素或链接的特定操作的另一种更好方法。

    限制Link s

    因此,当论文被实例化时,如果您希望永久限制与链接的所有交互,您可以这样做:

    var paper = new joint.dia.Paper({
      interactive: {
        useLinkTools: false,
        labelMove: false,
        vertexRemove: false,
        vertexAdd: false
        vertexMove: false,
        arrowheadMove: false,
      },
      gridSize: 10,
      drawGrid: true,
      model: graph,
      defaultLink: new joint.shapes.app.Link,
      // other properties ....
    })
    

    限制Element s

    如果您只想 限制所有元素的互动,那么:

    var paper = new joint.dia.Paper({
      interactive: {
        elementMove: false,
        addLinkFromMagnet: false,
      },
      // other properties ....
    })
    

    interactive提供功能(高度自定义)

    或者,如果您使用interactive属性值的函数,那么您就是 需要区分元素和链接,然后对它们进行操作。要限制仅链接互动,您只需在检测到这些内容时返回false

    var paper = new joint.dia.Paper({
      interactive: function (cellView) {
        if(cellView.model instanceof joint.dia.Link) {
          console.log('Link interaction');
          return false;
        }
        else {
          console.log('Element interaction of type:', cellView.model.get('type'));
          return true;
        }
      },
      // other properties ....
    })
    

    我的首选限制方法只是通过识别与某些来源相关的链接并为其返回false来完成:

    var paper = new joint.dia.Paper({
      interactive: function (cellView) {
        if(cellView.model instanceof joint.dia.Link) {
          console.log('Link interaction');
          var lSource = cellView.model.getSourceElement();
          if(lSource instanceof joint.shapes.app.AwesomeShape){
            // do not allow links connected to these sources to be modified
            console.log(`Links with ${lSource.get('type')} sources cannot be modified!`);
            return false;
          }
          // allow other links to be modified
          return true;
        }
        console.log('Element interaction of type:', cellView.model.get('type'));
        return true;
      },
      // other properties ....
    })