Focus-UI组件库C-MVC架构之Model篇

Focus UI是基于HTML5和C-MVC模式开发的UI组件库, 用于快速构建功能强大的高性能Web应用和数据可视化。

组件库提供了包括表格、树、列表、菜单在内的丰富而完善的各种组件(请参考Demo),快速轻量、简单易用、可扩展性是主要特点。

C-MVC架构

整个系统架构基于C-MVC模式,这里说的C-MVC指的是客户端的MVC(client-mvc),跟后台没有关系。 这里的MVC也不是传统意义上的MVC,而是由MVC演变出来的模型架构,之所以用MVC,是因为后续这些MVP/MVVM/MV*都是由经典的MVC衍生出来的。

整个架构分为数据模型、视图组件、和控制器三部分,由模型类驱动视图,模型和视图之间通过控制器(事件)进行绑定和交互,模型的变化通过控制器会及时反应到视图组件以更新显示,同时一个模型可以驱动多个视图。

使用者不需要繁琐的操作dom,只需要简单的操作模型即可,系统会根据模型变化自动更新视图。

本文主要介绍C-MVC架构的数据模型Model部分,Mode模型由数据元素Data和数据容器Provider组成。

数据元素Data

数据元素是经过封装的Object对象,是z.Data及其子类的对象,主要有两个功能:

  • 存放显示和业务相关的数据,比如name、image、id等
  • 事件派发,属性变化都会dispatch出事件

数据Data的使用方法如下:

                
                    /**
                     * 创建data对象
                     * 此处的new可以省略,Data内部做了处理。
                     * 参数为一个object,是data的初始化参数,可以省略
                     */
                    var data = new z.Data({
                        name: "focus ui"
                    });

                    /**
                     * 设置data属性,
                     * 可以单个设置,也可以通过object批量设置
                     */
                    data.set("version", "v1.1");
                    data.set({
                        url: "http://www.focus-ui.com",
                        email: "taozh1982@gmail.com"
                    });

                    /**
                     * 获取data属性&获取data所有属性
                     */
                    console.log(data.get("name"));//"focus ui"
                    console.log(data.gets());//属性object

                    /**
                     * 删除data属性
                     */
                    data.remove("email");
                
            

数据提供了事件派发,设置data的属性都会派发出事件。

                
                    /**
                     * 事件监听器
                     */
                    var listener = function (event) {
                        console.log(event);//{property: "version", new_value: "v1.1", old_value: undefined}
                    };
                    /**
                     * 添加事件监听
                     */
                    data.addChangeListener(listener);

                    /**
                     * 移除事件监听
                     */
                    data.removeChangeListener(listener);
                
            

一般不需要监听data的属性变化,后续介绍到容器Provider时,会详细介绍。

以上就是数据元素data的使用介绍,可以看到data的使用非常简单,只需要简单的get/set操作即可。

数据容器Provider

属性容器Provider有两个主要功能

  • 管理Data数据,data的增删改查等操作
  • 事件派发,当provider的data出现增删操作、管理的data属性发生变化、以及管理的data的index顺序发生变化时,provider都会派发出事件,View视图组件会根据这些事件更新视图。

管理Data数据

Provider提供了针对Data的增删改查操作方法

                
                    /**
                     * 创建Provider对象。
                     */
                    var provider = new z.Provider();

                    var data1 = new z.Data({name: "data1"});
                    var data2 = new z.Data({name: "data2"});
                    var data3 = new z.Data({name: "data3"});

                    /**
                     * 添加Data对象。
                     * 可以添加一个或者通过Array一次添加多个
                     */
                    provider.add(data1);
                    provider.add([data2, data3]);

                    /**
                     * 删除Data对象
                     */
                    provider.remove(data1);

                    /**
                     * 检查是否包含Data对象
                     */
                    console.log(provider.contains(data1));//false
                    console.log(provider.contains(data2));//true

                    /**
                     * 查找Data对象
                     * 可以通过属性/属性集合/回调函数进行查找
                     */
                    provider.find("name", "data2");//data2对象
                    provider.find({name: "data2"});//data2对象
                    provider.find(function (data) {//data3对象
                        return data.get("name") === "data3";
                    });

                    /**
                     * 过滤Data对象
                     * 可以通过属性/属性集合/回调函数进行过滤
                     */
                    provider.filter(function (data) {
                        return data.get("type") === "group"
                    });

                    /**
                     * 返回所有Data对象数组
                     */
                    var arr = provider.toArray();

                    /**
                     * 遍历所有Data数据
                     */
                    provider.each(function (data) {
                        console.log(data.get("name"));
                    });

                    /**
                     * 清除所有Data数据
                     */
                    provider.clear();
                
            

事件派发

Provider的另外一个重要功能就是事件派发,事件主要分三类:

  • provider中data的增删事件,当向provider添加数据,删除或清空数据时,provider会派发出事件。
  • provider中data的属性变化事件,当provider中的data属性发生变化时,provider会派发出事件。
  • provider中data的index顺序变化事件,当provider中的data顺序发生变化时,provider会派发出事件。

对于所有添加到provider的data,provider都添加了data的属性变化事件监听,当data属性发生变化时,provider会监听到事件,然后将事件进行转发。

这样就不用针对每一个data都添加属性变化事件监听了,只需要在provider添加即可,针对大量数据的情况,这种实现非常方便。

派发出的这些事件,会被view组件监听到,然后根据具体的事件更新组件。

事件监听代码如下:

                
                    /**
                     * provider中data的增删事件
                     */
                    provider.addProviderChangeListener(function (event) {
                        console.log(event);//{type: "add", data: $Data}
                    });

                    /**
                     * provider中data的属性变化事件
                     */
                    provider.addDataChangeListener(function (event) {
                        console.log(event);//{property: "name", new_value: "hello", old_value: "data2", data: $Data}
                    });

                    /**
                     * provider中data的index顺序变化事件
                     */
                    provider.addIndexChangeListener(function (event) {
                        console.log(event);//{data: $Data, new_index: 0, old_index: 1}
                    });
                
            

以上就是C-MVC架构的数据模型Model部分的主要内容。

请注意,在使用Focus-UI的过程中,视图组件上针对Data和Provider做了封装,大多数情况不会直接操作Data和Provider,但是在系统内部都是调用Data和Provider进行的操作。