Skip to content

创建 Component 文件

花生PeA edited this page Feb 23, 2019 · 5 revisions

一个 Short Night 时间线是由9个部件组成的,因此我们要首先创建9个文件。

文件结构如下:

Axis/
 |- index.ts
 |- AxisBody.ts
 |- AxisScale.ts
 |- AxisMilestone.ts
Event/
 |- index.ts
 |- EventBody.ts
 |- EventMark.ts
 |- EventAxis.ts
Timeline.ts

创建叶子组件

根据上方的 Component 结构图,这9个组件文件中除去/Timeline.ts/Axis/index.ts/Event/index.ts这3个文件,其他的都是属于叶子节点的文件。

叶子节点负责画东西,最简单的实现叶子节点的方法,只要实现draw方法即可。如轴体 AxisBody 的代码 /Axis/AxisBody.ts

import * as Engine from 'short-night';

export default class AxisBody extends Engine.AxisBody {
    theme = 'polar-day';

    draw() {
        return super.draw();
    }
}

上边代码中,我们导入了 Short Night 模块,然后声明了一个 AxisBody 类继承了 Short Night 中的 AxisBody。上边类中有写2个属性

  • theme:主题的名称,这个填入一个你喜欢的名字即可,确保所有 Component 用的是同一个 theme 名称即可
  • draw():当组件被画时调用的方法。这不是一个“钩子”,而是功能本身的函数。主题作者需要在 draw() 中完成将该组件“画上去”的工作。这里我们先简单的调用super.draw(),什么都不做。

其他叶子节点的文件也都是一样,只不过要将上边代码中的AxisBody替换到对应的 Component 名称。


文件:/Axis/AxisMilestone.ts

import * as Engine from 'short-night';

export default class AxisMilestone extends Engine.AxisMilestone {
    theme = 'polar-day';

    draw() {
        return super.draw();
    }
}

文件:/Axis/AxisScale.ts

import * as Engine from 'short-night';

export default class AxisScale extends Engine.AxisScale {
    theme = 'polar-day';

    draw() {
        return super.draw();
    }
}

文件:/Event/EventMark.ts

import * as Engine from 'short-night';

export default class EventMark extends Engine.EventMark{
    theme = 'polar-day';

    draw() {
        return super.draw();
    }
}

文件:/Event/EventAxis.ts

import * as Engine from 'short-night';

export default class EventAxis extends Engine.EventAxis {
    theme = 'polar-day';

    draw() {
        return super.draw();
    }
}

文件:/Event/EventBody.ts

import * as Engine from 'short-night';

export default class EventBody extends Engine.EventBody {
    theme = 'polar-day';

    draw() {
        return super.draw();
    }
}

6个文件内容除了类名、继承的类名、文件名不同外,没有其他区别。

注意类名、继承的类名、文件名三者保持统一

创建逻辑组件

接下来创建3个逻辑组件,也就是9个组件中除去6个叶子组件所剩余的3个。

你以为叶子组件的“代码好简单”到此为止了吗?不,逻辑组件的代码更简单。以/Event/index.ts为例:

import * as Engine from 'short-night';
import EventBody from './EventBody';
import EventAxis from './EventAxis';
import EventMark from './EventMark';

export default class Event extends Engine.Event {
    theme = 'polar-day';

    mark :EventMark = null as any;
    body :EventBody = null as any;
    axis :EventAxis = null as any;

    bodyConstructor = EventBody;
    axisConstructor = EventAxis;
    markConstructor = EventMark;

}

可以看到,逻辑组件 Event 仅仅是声明了自己:子节点的构造函数、子节点的类型、主题名。

而关于上边3个的as any,这是为了让叶子 Component 的实例化在引擎内部进行的,所以不用担心。如果你不使用this.bodythis.axisthis.mark的话,你也可以省略子节点的类型,让代码只有10行!

import * as Engine from 'short-night';
import EventBody from './EventBody';
import EventAxis from './EventAxis';
import EventMark from './EventMark';

export default class Event extends Engine.Event {
    theme = 'polar-day';

    bodyConstructor = EventBody;
    axisConstructor = EventAxis;
    markConstructor = EventMark;

}

相同的,/Timeline.ts/Axis/index.ts也仅仅是声明自己的子组件和主题名:

文件/Axis/index.ts

import * as Engine from 'short-night';
import AxisBody from './AxisBody';
import AxisMilestone from './AxisMilestone';
import AxisScale from './AxisScale';

export default class Axis extends Engine.Axis {
    theme = 'colors';

    bodyConstructor = AxisBody;
    milestoneConstructor = AxisMilestone;
    scaleConstructor = AxisScale;

}

文件/Timeline.ts

import * as Engine from 'short-night';
import Axis from './Axis';
import Event from './Event';

export default class Timeline extends Engine.Timeline {
    theme = 'colors';

    axisConstructor = Axis;
    eventConstructor = Event;
}

是不是感觉太简单,简单到已经开始慌了?

代码量少是非常正常的,哪怕是华丽的 Rules 也仅仅只有不到300行代码。

原因很简单,因为画一个时间线虽然足够复杂与繁琐,但是其中重复性的工作却有很多,或者说非常多。正是因为重复的工作量有如此之多,所以 Short Night 是一个“引擎”,而不是一套可以直接画出来的“工具”。