Is there any way that a NodeView is notified when a node is moved in the document?
I’m building react backed NodeViews that are rerendered when the update function is called. When attributes are set this correctly triggers a rerender but moving a node doesn’t seem to trigger an update. So React never knows that it should rerender on move.
The reason I want to rerender is that I have “move block up” buttons that should become disabled once the block is the first in the document:
I’ve been able to force this to work by triggering a rerender in the function that moves the block:
RangeError: Position undefined out of range
at Function.resolve (index.js?6f27:945)
at Function.resolveCached (index.js?6f27:968)
at Node.resolve (index.js?6f27:1239)
at Object.get canMoveNodeUp [as canMoveNodeUp] (VM9986 nodeViewActions.js:49)
Am I on the right path and just have a bug in my canMoveNodeUp code causing the range errors? or is there another way I can trigger rerenders when the state changes?
Node views don’t really get to know about their position in the document—they are rendered and then left alone as long as the node stays the same, since constantly calling their update methods when something somewhere in the document changed would be expensive.
There is one way to communicate with node views, and that is to add node decorations to them from external code. When their decorations change, the update method will be called, and the decorations are passed as one of its arguments.
Ok, cool. I’m using MobX to control rendering so if I add a decoration of their current position to NodeViews then MobX can limit the rerenders to only if some computed property has changed as a result of the new position. That’ll help limit the performance cost. Thanks.
Would you be open to adding a way to notify the NodeView if it’s position has changed? Not necessarily extending the functionality of the update function as I wouldn’t want to break other implementations.
If you really want to do this, you can have your nodeviews register themselves somewhere on init (and unregister on .destroy()), and just blast out a notification every time the document changes.
Does the order matter at all? If I remove at 8 then insert at 10 in the same transaction will the positions be mapped correctly even if the remove means the subsequent insert would be at 8 by the end of the transaction?
Ok, the order does matter. Switching the order on the moveUp means I replace the wrong content (text in the paragraph node above) instead of the nodeView.
The moveDown works because the nodeView is destroyed and recreated. I would need to calculate the new position after the insert of the copy nodeView in order to properly delete the original nodeView.