retejs / rete

JavaScript framework for visual programming
https://retejs.org
MIT License
10.17k stars 653 forks source link

Rete V2 : Passing Multiple Arguments to Custom Nodes (with Vue) #627

Closed JosueGauthier closed 1 year ago

JosueGauthier commented 1 year ago

Hello,

I'm using Vue3.js and Rete to make a simple task graph builder.

I'd like to be able to pass several arguments to my customs nodes but I can't figure out how to do it,

For example, if I only have one CustomNode.vue model, when I create a CustomNode.vue type node in the editor, I could say that it will be called "MyNode1", and add a parameter param1 and set this parameter to 1 for example.

How do I rewrite the Node constructor ?

CustomNode.vue

export default defineComponent({
  props: ['data', 'emit'],

  methods: {
    //...
  },
  //...
})

editor.ts


render.addPreset(
    Presets.classic.setup({
      customize: {
        node(context) {
          console.log(context.payload, CustomNode);
          if (context.payload.label === "Custom") {
            return CustomNode;
          }
          return Presets.classic.Node;
        },
        socket(context) {
          return CustomSocket;
        },
        connection(context) {
          return CustomConnection;
        },
      },
    })
  );

  connection.addPreset(ConnectionPresets.classic.setup());

  addCustomBackground(area);

  editor.use(area);
  area.use(connection);
  area.use(render);

  AreaExtensions.simpleNodesOrder(area);

  const a = new ClassicPreset.Node("Custom");
  a.myTitle = "MyNode1";
  a.param1 = 1;
  a.addOutput("a-output1", new ClassicPreset.Output(socket));
  a.addInput("a-input1", new ClassicPreset.Input(socket));
  await editor.addNode(a);

Thank you !

Ni55aN commented 1 year ago
export default defineComponent({
  props: ['data', 'emit'],
  /// ....

data is your new ClassicPreset.Node("Custom") which is passed by reference which means you can add any number of properties

JosueGauthier commented 1 year ago

Hello Ni55aN and thank you for your help,

I solve the issue but not the way you explain, so I'm curious if you have a small example. Yes I understand I can add any number of properties but how to instantiate them inside the editor.ts ?

My solution is something like this


class NodeExtendedV2 extends ClassicPreset.Node<
  Record<string, ClassicPreset.Socket>,
  Record<string, ClassicPreset.Socket>,
  Record<
    string,
    | ButtonControl
    | ProgressControl
    | ClassicPreset.InputControl<"number">
    | ClassicPreset.InputControl<"text">
  >
> {
  constructor(public label: string, public title: string) {
    super(label);
    this.title = title;
  }

so i can create a new NodeExtendedV2 :


 const c = new NodeExtendedV2("CustomV2", "Bobo");
  c.addOutput("c-output1", new ClassicPreset.Output(socket));
  c.addInput("c-input1", new ClassicPreset.Input(socket));
  await editor.addNode(c);

and use inside my CustomNodeV2.vue I can use it like this {{ data.title }}

Thank you again,

Ni55aN commented 1 year ago

in your first example you also can use {{ data.myTitle }} if the template is not statically typed.

The only difference is that by extending the Node (which is basically the recommended way if you need to create different node classes) it is statically typed

 const a = new ClassicPreset.Node("Custom");
 a.myTitle = "MyNode1";
 a.param1 = 1;

I got it. This is TypeScript-specific issue because ClassicPreset.Node doesn't have myTitle and param1 and it will throw an error. Certainly, in such cases it is necessary to explicitly define the type with these fields

JosueGauthier commented 1 year ago

Ok thank you for you anwser ! I close the issue so.