dart-tagtree, 在省飞镖中,像用户界面框架一样

分享于 

7分钟阅读

GitHub

  繁體 雙語
A React-like UI framework in Dart
  • 源代码名称:dart-tagtree
  • 源代码网址:http://www.github.com/google/dart-tagtree
  • dart-tagtree源代码文档
  • dart-tagtree源代码下载
  • Git URL:
    git://www.github.com/google/dart-tagtree.git
    Git Clone代码到本地:
    git clone http://www.github.com/google/dart-tagtree
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/google/dart-tagtree
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    
    TagTree

    TagTree是一个用 Dart 编写的实验UI框架,灵感来自于。

    免责声明

    这不是官方的Google产品。 如果你愿意在生产 Dart 应用程序中使用 TagTree,不支持,也不打算在生产应用程序中使用该代码。

    概念

    TagTree的三个类是 Tag Tag Animator Animator Animator Animator Animator Animator Place Place Place Place Place。 你可能会把它们看作是的一种替代方式。

    标记

    [Tag] 1 只是一个实现记录的类:

    
    class GridView extends Tag {
    
    
     final Grid grid;
    
    
     final List<String> palette;
    
    
     final Function onPaint;
    
    
     const GridView({this.grid, this.palette, this.onPaint});
    
    
    
     @override
    
    
     get animator => null;//TODO: explain
    
    
    }
    
    
    
    

    在本例中,GridView标记有三个属性,它们只是 Dart 字段。 基于标签的网格和 palette属性包含标记使用的数据,onPaint是事件处理程序。 HTML元素不同,这些属性可以是各种 Dart 类型,而不仅仅是字符串。

    像HTML元素一样,标签可以有子元素。 GridView没有任何子对象,但是如果它有的话,它们将进入另一个名为内部的域。 但这只是一个惯例;标签可以有任何你喜欢的字段。

    HTML元素不同,标签永远不应该改变。 不应该是它的后代;TagTree中的标记树应该是深度不可以变的,除了可以指向可以变对象的函数。 ( 飞道并不强制这样做,但是你可以将标签作为一个常量构造函数提供。)

    动画动画

    为了给标记提供一些行为,你需要编写一个 [Animator] 2

    
    class ButtonDemo extends Tag {
    
    
     const ButtonDemo();
    
    
     @override
    
    
     get animator => const MyButtonAnimator();
    
    
    }
    
    
    
    class MyButtonAnimator extends Animator<ButtonDemo, int> {
    
    
     const MyButtonAnimator();
    
    
    
     @override
    
    
     Place start(_) => new Place(0);
    
    
    
     @override
    
    
     Tag renderAt(Place<int> p, _) {
    
    
    
     onClick(_) {
    
    
     print("button clicked");
    
    
     p.nextState = p.nextState + 1;
    
    
     }
    
    
    
     return $.Div(inner: [
    
    
     $.H1(inner:"Button Demo"),
    
    
     $.Div(inner:"Clicks: ${p.state}"),
    
    
     $.Button(onClick: onClick, inner:"Click here"),
    
    
     ]);
    
    
     }
    
    
    }
    
    
    
    

    就像你所期望的那样,动画师会生成动画。 动画只是标记流,或者是标记树的流,因为标记可以拥有后代。 你可以把这些树想象成动画的一个框架。 标记树调用 renderAt 方法来生成每个帧。

    对于动画师来说,输入是另一个流,通常是标记。 或者,一个标记流,它是TagTree如何表示更改的标记。

    上面 示例,输入( ButtonDemo标记) 没有字段并且不会更改,因此MyButtonAnimator会按照自己的速度来忽略它,通过设置位置的nextState 属性来生成新的动画帧。

    这显示了动画师和普通的HTML模板之间的区别。 模板是被动( 无状态) ;它的输出不会改变,除非它的输入改变。 动画师可以充当扩展每个输入标签的模板。 但它还可以其他方式获取输入,并且可能具有内部状态。 animator流输出的帧速率与它的输入流无关。

    结果类似于幻灯片放映,其中一些幻灯片包含动画gif或者视频。 当你前进到下一张幻灯片时屏幕会改变,但是幻灯片本身也可以自己移动。

    用类似的方式,TagTree中的每个自定义标记都呈现为单独的动画。 这些动画可以嵌套到任意数量的级别,它们形成动态的树结构,类似于网页中的HTML元素。

    因此TagTree可以被看作是像UI组件库一样的React,实现虚拟 DOM。 React一样,虚拟DOM有表示常规HTML元素和你自己编写的自定义标记的标记。 但是TagTree使用了不同的隐喻来实现类似的功能。

    位置

    由于TagTree中嵌套动画可以独立移动,所以我们需要一种方法来跟踪它们的状态。 在TagTree中,动画的状态总是存储在 [Place] 3中。 这允许TagTree在不同地点运行的多个动画之间自由共享动画。

    如果你想使用面向对象的面向对象的样式,你可以将它的子类化为小部件对象。 TagTree将动画中的每个地方隔离,所以这只是一个实现细节。 动画之间的所有通信都使用标记流和事件回调进行。

    可选特性

    实际上,动画可以移动的第三个方法是: 它的主题可以改变。一个主题提供一系列的标签,并且开关主题通常会重新启动任何动画。 ( 主题可以被认为是执行依赖注入的一种方式。)

    TagTree提供了基于简单的json编解码器和基本支持 RPC,因这里可以通过网络发送标记树及它的回调事件。 这样,用户界面就可以在客户端和服务器之间分离,使用 web socket。 ( 这样做有一个有趣的演示,但它需要更多的工作来安全可以靠地使用于localhost之外的东西。)

    TemplateTag和AnimatedTag是结合了标记及其动画的便捷类。 当你不关心主题或者RPC时,它们是一个有用的捷径,在大多数例子中都是这样。

    示例

    我将几个 [Dart examples] 4 转换为 TagTree,以及所有的[examples from React's front page] 5. [PixelPaint] 6插件是一个可以完全在浏览器或者客户端服务器上运行的大示例。

    我还没有设置在线演示页面,因这里现在你需要检查存储库并从 inside 启动 Dart 编辑器。

    接触

    电子邮件:brian+tagtree@slesinsky.org

    Google Plus: https://plus.google.com/+BrianSlesinsky

    Twitter: @skybrian


      framework  react  LIKE  DART