Skip to content

Commit

Permalink
fix: 删除元素不参与布局计算
Browse files Browse the repository at this point in the history
  • Loading branch information
zengyue committed May 26, 2021
1 parent 5dba80f commit d05753e
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/jsx/src/css-layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
29 changes: 27 additions & 2 deletions packages/jsx/src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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 = {
Expand All @@ -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++) {
Expand All @@ -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);
}
136 changes: 135 additions & 1 deletion packages/jsx/test/render.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

import * as F2 from '@antv/f2';
import { render, jsx } from '../src';
import { ELEMENT_DELETE } from '../src/elementStatus';

const { G } = F2;

Expand Down Expand Up @@ -139,7 +140,7 @@ describe('render', () => {
});
});

describe.skip('render style alias', () => {
describe('render style alias', () => {
it('group', () => {
const container = canvas.addGroup();
const group = render(
Expand Down Expand Up @@ -333,4 +334,137 @@ describe('layout', () => {

// container.remove(true);
});

describe('delete element', () => {
it('删除元素不参布局计算', () => {
const container = canvas.addGroup();
const groupJSXElement = (
<group style={{
flexDirection: 'row',
width: 200,
height: 200,
flexWrap: 'wrap',
}}>
<rect
style={{
flex: 1,
}}
attrs={{
fill: '#f00',
}}
/>
<rect
style={{
flex: 1,
}}
attrs={{
fill: '#0f0',
}}
/>
<group
style={{
flex: 1,
flexDirection: 'row',
}}
>
<rect
style={{
flex: 1,
}}
attrs={{
fill: '#00f',
}}
/>
<rect
style={{
flex: 1,
}}
attrs={{
fill: '#0f0',
}}
/>
</group>
</group>
);
// 把中间的元素标记为删除
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 = (
<group style={{
flexDirection: 'row',
width: 200,
height: 200,
flexWrap: 'wrap',
}}>
<rect
style={{
flex: 1,
}}
attrs={{
fill: '#f00',
}}
/>
<rect
style={{
flex: 1,
}}
attrs={{
fill: '#0f0',
}}
/>
</group>
);
// 把中间的元素标记为删除
// @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);
});
});
});

0 comments on commit d05753e

Please sign in to comment.