Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: x6-vue-shape teleport render #3378

Closed
wants to merge 1 commit into from

Conversation

0jinxing
Copy link
Contributor

Description

Motivation and Context

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Enhancement (changes that improvement of current feature or performance)
  • Refactoring (changes that neither fixes a bug nor adds a feature)
  • Test Case (changes that add missing tests or correct existing tests)
  • Code style optimization (changes that do not affect the meaning of the code)
  • Docs (changes that only update documentation)
  • Chore (changes that don't modify src or test files)

Self Check before Merge

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

@x6-bot x6-bot bot added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. PR: unreviewed PR does not have any reviews. fix labels Mar 14, 2023
@x6-bot
Copy link
Contributor

x6-bot bot commented Mar 14, 2023

👋 @0jinxing

💖 Thanks for opening this pull request! 💖

Please follow the contributing guidelines. And we use semantic commit messages to streamline the release process.

Examples of commit messages with semantic prefixes:

  • fix: don't overwrite prevent_default if default wasn't prevented
  • feat: add graph.scale() method
  • docs: graph.getShortestPath is now available

Things that will help get your PR across the finish line:

  • Follow the TypeScript, JavaScript, CSS and React coding style.
  • Run npm run lint locally to catch formatting errors earlier.
  • Document any user-facing changes you've made.
  • Include tests when adding/changing behavior.
  • Include screenshots and animated GIFs whenever possible.

We get a lot of pull requests on this repo, so please be patient and we will get back to you as soon as we can.

@0jinxing
Copy link
Contributor Author

vue3 启用 teleport @antv/x6-vue-shape 多画布实例,会出现渲染异常

@0jinxing
Copy link
Contributor Author

2023-03-14.18.47.02.mov

@0jinxing
Copy link
Contributor Author

0jinxing commented Mar 14, 2023

我记得 1.x 版本是有提供 一个 类似 viewId 来划分 不同画布实例,
2.x 版本是出于什么原因,去除了这个 功能。

我想 Teleport 可选 传入 graph 实例 来划分 items,是不是 会比 1.x 版本 viewId 来的更加直观

@lloydzhou
Copy link
Contributor

1.x版本最开始的时候,TeleportContainer需要使用unique_graph_id,每个画布自己维护一份。

2.x版本的getTeleport不再需要和画布绑定,只要全局渲染一个TeleportContainer就可以了。

改成这样,接口会和x6-react-shape更统一。

@0jinxing
Copy link
Contributor Author

1.x版本最开始的时候,TeleportContainer需要使用unique_graph_id,每个画布自己维护一份。

🤔, 使用 teleport 是希望 node 组件 可以用到 父组件的 provide context,

@0jinxing
Copy link
Contributor Author

2.x版本的getTeleport不再需要和画布绑定,只要全局渲染一个TeleportContainer就可以了。

像这样,好像达不到目的

@0jinxing
Copy link
Contributor Author

0jinxing commented Mar 15, 2023

1.x版本最开始的时候,TeleportContainer需要使用unique_graph_id,每个画布自己维护一份。

2.x版本的getTeleport不再需要和画布绑定,只要全局渲染一个TeleportContainer就可以了。

改成这样,接口会和x6-react-shape更统一。

是否 可以 Teleport 提供一个 可选项 绑定 画布

import { defineComponent, provide } from "vue"
const Teleport = getTeleport();

const Graph1 = defineComponent({
  setup() {
    // 期望 node 节点可以获取到 bizContext1
    provide("bizContext1", {})
    return () => <div>
      <div class="graph1" />
      <Teleport />
    </div>
  }
})

const Graph2 = defineComponent({
  setup() {
    // 期望 node 节点可以获取到 bizContext2
    provide("bizContext2", {})
    return () => <div>
      <div class="graph2" />
      <Teleport />
    </div>
  }
})

const App = defineComponent({
  setup() {
    return () => <div>
      <Graph1 />
      <Graph2 />
    </div>
  }
})

可以满足类似上面的场景,

🤔,不知道我这样表达的是否清楚,或者这样的需求 是否合理

@0jinxing
Copy link
Contributor Author

要不,考虑合并下 🐶 @lloydzhou

@lloydzhou
Copy link
Contributor

要不,考虑合并下 dog @lloydzhou

  1. 合并代码的事情需要 @NewByVector 处理
  2. 这个改动,如果是2.0.10的开发者直接升级会不会有问题?是否应该增加新的测试用例?是否需要更新文档以及官方示例?

@0jinxing
Copy link
Contributor Author

要不,考虑合并下 dog @lloydzhou

  1. 合并代码的事情需要 @NewByVector 处理
  2. 这个改动,如果是2.0.10的开发者直接升级会不会有问题?是否应该增加新的测试用例?是否需要更新文档以及官方示例?

2.0.10 升级不会有问题,测试用例和文档应该是需要补充下。

@lloydzhou
Copy link
Contributor

你前面提到的希望能在Graph1和Graph2内部通过provide的API分别共享两个不同的context,让Teleport能同时读到两个值。或许你可以试试把这两个provide放到外层组件里面

const App = defineComponent({
  setup() {
    const context = reactive({
      value1: {},
      value2: {},
    })
    const context2 = reactive({})
    provide("bizContext1", {update: (value)=> context.value1 = value, value: context.value1 })
    provide("bizContext2", {update: (value)=> context.value2 = value, value: context.value2 })
    return () => <div>
      <Graph1 />
      <Graph2 />
      <Teleport />
    </div>
  }
})

然后,Graph1和Graph2内部使用inject分别拿到不同的update方法去更新context的值。Teleport中的节点,也可以通过inject分别拿到不同的value值

@minikinl
Copy link

你前面提到的希望能在Graph1和Graph2内部通过provide的API分别共享两个不同的context,让Teleport能同时读到两个值。或许你可以试试把这两个provide放到外层组件里面

const App = defineComponent({
  setup() {
    const context = reactive({
      value1: {},
      value2: {},
    })
    const context2 = reactive({})
    provide("bizContext1", {update: (value)=> context.value1 = value, value: context.value1 })
    provide("bizContext2", {update: (value)=> context.value2 = value, value: context.value2 })
    return () => <div>
      <Graph1 />
      <Graph2 />
      <Teleport />
    </div>
  }
})

然后,Graph1和Graph2内部使用inject分别拿到不同的update方法去更新context的值。Teleport中的节点,也可以通过inject分别拿到不同的value值

如果个数不定,需要通过 for 循环创建的 Graph1 ... GraphN 的话,不同的 Graph 如何知应该 inject 哪个呢。

也许有一些奇技淫巧能实现,但总感觉怪怪的,终是不如每个 Graph 使用自己的 Teleport

@lloydzhou
Copy link
Contributor

其实这里提到的需求是希望Teleport内部的节点,能通过inject的方式拿到自己画布的一些数据。

但是,节点(Component)与画布(Graph)之间通信不一定非要使用inject的方式。
其实,x6官方推荐的做法是给节点设置data(node.setData),使用这种方式通信就可以了。

@lloydzhou
Copy link
Contributor

@minikinl @0jinxing

对了,其实我试过另一种封装第三方框架组件的模式
https://github.com/lloydzhou/x6-html-shape

  1. 不管是哪种框架,抽象一个统一的render接口进行接入
  2. 接入的最小的“粒度”是节点

比如:一个vue的实现的节点抽象一个render函数进行注册,多个类型的节点就抽象多个render函数进行注册
其实这里复杂度并没有增加,官方标准的流程也是每一种节点需要register进去

  1. 针对支持portal或者teleport的节点。与之对应的,就会出现很多个对应的Container
import createRender from 'x6-html-shape/dist/teleport'

// 包装节点
const [render1, Container1] = createRender(Component1)
const [render1, Container2] = createRender(Component2)

// 注册节点
register({shape: 'vue3-teleport-node1', render1})
register({shape: 'vue3-teleport-node2', render2})

// 渲染的时候,需要分别挂载到模板内部,最终使用开发者工具审查的时候,每一个Container下面都是一种类型的节点
<template>
  <Container1 />
  <Container2 />
  <div ref="graph" />
</template>
  1. 不过,这种抽象模式,也只是将不同类型的节点划分到不同的Container下,并没有针对画布进行划分。

@0jinxing
Copy link
Contributor Author

其实这里提到的需求是希望Teleport内部的节点,能通过inject的方式拿到自己画布的一些数据。

但是,节点(Component)与画布(Graph)之间通信不一定非要使用inject的方式。 其实,x6官方推荐的做法是给节点设置data(node.setData),使用这种方式通信就可以了。

是的,这样也能到达目的。
就是之前没注意 遇到这种情况

@cc932636456
Copy link

你前面提到的希望能在Graph1和Graph2内部通过provide的API分别共享两个不同的context,让Teleport能同时读到两个值。或许你可以试试把这两个provide放到外层组件里面

const App = defineComponent({
  setup() {
    const context = reactive({
      value1: {},
      value2: {},
    })
    const context2 = reactive({})
    provide("bizContext1", {update: (value)=> context.value1 = value, value: context.value1 })
    provide("bizContext2", {update: (value)=> context.value2 = value, value: context.value2 })
    return () => <div>
      <Graph1 />
      <Graph2 />
      <Teleport />
    </div>
  }
})

然后,Graph1和Graph2内部使用inject分别拿到不同的update方法去更新context的值。Teleport中的节点,也可以通过inject分别拿到不同的value值

如果个数不定,需要通过 for 循环创建的 Graph1 ... GraphN 的话,不同的 Graph 如何知应该 inject 哪个呢。

也许有一些奇技淫巧能实现,但总感觉怪怪的,终是不如每个 Graph 使用自己的 Teleport

如果两个画布没有共属关系,这种方法就不太满足了把,我现在页面上两个画布都用到了teleport,但两个画布组件没有任何关系,也放不在一起,这个时候因为teleport,切换页面画布的时候就会重复渲染

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fix PR: unreviewed PR does not have any reviews. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants