Как предотвратить изменение ссылок или элементов?

Мне нужно ограничить взаимодействие пользователя с определенными ссылками и элементами. Например, если пользователь переместит или удалит элемент, последнее состояние этого элемента сразу же отобразится, и график не изменится.

В идеале я ищу простое свойство, которое можно добавить при создании элемента, что предотвращает все изменения, например. isModifiable: false.

Поскольку я не смог найти его, я использовал событие change и не очень элегантное рекурсивное решение для ссылок (добавлено как ответ ниже, теперь отредактировано с альтернативным и лучшим решением).

Существует ли идеальный метод для остановки или ограничения изменений?


person CPHPython    schedule 09.01.2018    source источник


Ответы (2)


Вы должны запретить пользователю совершать действия в документе, а не запрещать программисту вносить изменения в график.

См. параметр interactive < /a> для 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');
person Roman    schedule 10.01.2018

Индивидуальное Element/Link ограничение

Мне удалось частично решить эту проблему, изменив события, связанные с ячейками, например. для joint.dia.Link:

  1. Добавьте к событию change пользовательскую функцию;
  2. После запуска изменения удалите недавно измененную ссылку из графика;
  3. Используйте неповрежденный клон исходной ссылки и снова клонируйте его для использования в качестве вновь восстановленной ссылки;
  4. Добавьте эту же функцию к событию клонированной ссылки change;
  5. Добавьте клонированную ссылку на график.

Итак, это будут:

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);

Как только пользователь нажимает кнопку удаления, или пытается перетащить ссылку, или что-то еще, визуальных изменений буквально не происходит.

Это может быть не очень элегантное или высокопроизводительное решение (из-за многократного клонирования), и я заметил это в период, когда токен отправляется по ссылке, пользователь по-прежнему может его удалить. Но если у вас есть очень специфические ссылки/элементы после их создания, которые вам нужно ограничить, это все еще эффективно.

Бумага interactive имущественных ограничений

Это альтернативный лучший способ ограничить определенные действия со всеми элементами или ссылками в документе с помощью joint.Paper.prototype.options.interactive, как предложено Романом в другом ответе.

Ограничить Links

Итак, когда документ создан, если вы хотите, чтобы все взаимодействия со ссылками были постоянно ограничены, вы можете просто сделать:

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 ....
})

Ограничить Elements

Если вы хотите только ограничить взаимодействие всех элементов, то:

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 ....
})
person CPHPython    schedule 09.01.2018
comment
Для ограничения только определенных событий в элементе/ссылке с помощью метода функции, вот пример ограничения добавления вершины, где им нужно только вернуть { vertexAdd: false }. - person CPHPython; 15.01.2018