diff --git a/packages/jsx/src/css-layout.ts b/packages/jsx/src/css-layout.ts
index 2b4248f49..eebcd2dfe 100644
--- a/packages/jsx/src/css-layout.ts
+++ b/packages/jsx/src/css-layout.ts
@@ -1206,6 +1206,7 @@ function layoutNode(node, parentMaxWidth, parentDirection) {
/* eslint-enable */
function computeLayout(node) {
+ if (!node) return node;
const { style, children } = node;
if (style) {
fillNodes(node);
diff --git a/packages/jsx/src/render.ts b/packages/jsx/src/render.ts
index 2bbd152ea..5fe5ae992 100644
--- a/packages/jsx/src/render.ts
+++ b/packages/jsx/src/render.ts
@@ -3,6 +3,7 @@ import { extendMap, batch2hd } from '@ali/f2x-util';
import computeLayout from './css-layout';
import getShapeAttrs from './shape';
import getAnimation from './animation';
+import { ELEMENT_DELETE } from './elementStatus';
// 转换成布局所需要的布局树
function createNodeTree(element: any, container: any) {
@@ -62,7 +63,7 @@ function mergeLayout(parent: any, layout: any) {
function createElement(node: any, container: any, parentLayout: any) {
- const { _cache = {}, key, ref, type, props, style, attrs, layout: originLayout, children, status } = node;
+ const { _cache = {}, key, ref, type, props, style, attrs, layout: originLayout, renderChildren, children: nodeChildren, status } = node;
const layout = mergeLayout(parentLayout, originLayout);
const elementAttrs = {
@@ -81,6 +82,8 @@ function createElement(node: any, container: any, parentLayout: any) {
status,
attrs: elementAttrs
});
+ // 如果元素被删除了,就不会有renderChildren, 直接拿node.children渲染
+ const children = renderChildren ? renderChildren : nodeChildren;
// 只有group才需要处理children
if (children && children.length) {
for (let i = 0, len = children.length; i < len; i++) {
@@ -102,11 +105,33 @@ function createElement(node: any, container: any, parentLayout: any) {
return element;
}
+// 过滤删除的元素,让其不参与布局计算
+function filterDeleteElement(node) {
+ const { status, children } = node;
+ if (status === ELEMENT_DELETE) {
+ return null;
+ }
+ if (!children || !children.length) {
+ return node;
+ }
+
+ const newChildren = children.filter((child) => {
+ return !!filterDeleteElement(child);
+ });
+
+ // 要保留引用
+ node.children = newChildren;
+ node.renderChildren = children;
+
+ return node;
+}
+
export default (element: JSX.Element, container: any) => {
if (!element) {
return;
}
const nodeTree = createNodeTree(element, container);
- computeLayout(nodeTree);
+ const computeLayoutTree = filterDeleteElement(nodeTree);
+ computeLayout(computeLayoutTree);
return createElement(nodeTree, container, null);
}
diff --git a/packages/jsx/test/render.test.tsx b/packages/jsx/test/render.test.tsx
index 02cdc5d0b..74f857213 100644
--- a/packages/jsx/test/render.test.tsx
+++ b/packages/jsx/test/render.test.tsx
@@ -1,6 +1,7 @@
import * as F2 from '@antv/f2';
import { render, jsx } from '../src';
+import { ELEMENT_DELETE } from '../src/elementStatus';
const { G } = F2;
@@ -139,7 +140,7 @@ describe('render', () => {
});
});
-describe.skip('render style alias', () => {
+describe('render style alias', () => {
it('group', () => {
const container = canvas.addGroup();
const group = render(
@@ -333,4 +334,137 @@ describe('layout', () => {
// container.remove(true);
});
+
+ describe('delete element', () => {
+ it('删除元素不参布局计算', () => {
+ const container = canvas.addGroup();
+ const groupJSXElement = (
+
+
+
+
+
+
+
+
+ );
+ // 把中间的元素标记为删除
+ groupJSXElement.props.children[1].status = ELEMENT_DELETE;
+ groupJSXElement.props.children[2].props.children[1].status = ELEMENT_DELETE;
+ const group = render(groupJSXElement, container);
+ canvas.draw();
+
+ const children = group.get('children');
+ expect(children[0].get('attrs').x).toBe(0);
+ expect(children[0].get('attrs').y).toBe(0);
+ expect(children[0].get('attrs').width).toBe(100);
+ expect(children[0].get('attrs').height).toBe(200);
+
+ expect(children[1].get('attrs').x).toBe(0);
+ expect(children[1].get('attrs').y).toBe(0);
+ expect(children[1].get('attrs').width).toBe(0);
+ expect(children[1].get('attrs').height).toBe(0);
+
+ expect(children[2].get('attrs').x).toBe(100);
+ expect(children[2].get('attrs').y).toBe(0);
+ expect(children[2].get('attrs').width).toBe(100);
+ expect(children[2].get('attrs').height).toBe(200);
+
+ const subChildren = children[2].get('children');
+ expect(subChildren[0].get('attrs').x).toBe(100);
+ expect(subChildren[0].get('attrs').y).toBe(0);
+ expect(subChildren[0].get('attrs').width).toBe(100);
+ expect(subChildren[0].get('attrs').height).toBe(200);
+
+ expect(children[1].get('attrs').x).toBe(0);
+ expect(children[1].get('attrs').y).toBe(0);
+ expect(children[1].get('attrs').width).toBe(0);
+ expect(children[1].get('attrs').height).toBe(0);
+
+ });
+
+ it('删除元素不参布局计算-根元素', () => {
+ const container = canvas.addGroup();
+ const groupJSXElement = (
+
+
+
+
+ );
+ // 把中间的元素标记为删除
+ // @ts-ignore
+ groupJSXElement.status = ELEMENT_DELETE;
+ const group = render(groupJSXElement, container);
+ canvas.draw();
+
+ const children = group.get('children');
+ expect(children.length).toBe(2);
+ expect(children[0].get('attrs').x).toBe(0);
+ expect(children[0].get('attrs').y).toBe(0);
+ expect(children[0].get('attrs').width).toBe(0);
+ expect(children[0].get('attrs').height).toBe(0);
+
+ expect(children[1].get('attrs').x).toBe(0);
+ expect(children[1].get('attrs').y).toBe(0);
+ expect(children[1].get('attrs').width).toBe(0);
+ expect(children[1].get('attrs').height).toBe(0);
+ });
+ });
});