smartjs - DataManager API

dataServices


數據服務的管理器;首先看下具體的代碼html

//數據服務
    dataServices = st.factory({
        name: "dataServices",
        proto: {
            //經過操做方法;type:操做類型; op:操做參數
            operate: function(type, op) {…………},
            //查詢方法;op:操做參數
            search: function(op) {…………},
            //更新方法;op:操做參數
            update: function(op) {……}
        },
        base: {
            //查詢接口
            search: function(op) {},
            //更新接口
            update: function(op) {},
            //通用初始化參數接口
            initOptions : function(op){}
        }
    })

使用factory建立,加入了三個方法operate,search,update。使用的時候,直接經過這三個方法來操做具體註冊的數據服務(在op中設定dsType)。git

同時base定義了三個數據服務的三個基類接口,search,update,initOptions;github

 

op:既設置的參數(options,在smartjs中統一作op的簡寫),只有六個固定參數。其餘都是都是由具體的數據服務定義;api

    op = {
        //數據服務類型
        dsType : str,
        //過濾參數
        param :obj,
        //過濾器
        fitler : fn | obj
        //更新的數據
        data :obj,
        //成功之後執行的方法
        success : success,
        //失敗之後執行的方法
        error : error
    };


其中,param與filter能夠根據不一樣的數據服務類型來區別使用,好比只是客戶端的能夠使用filter,服務端的能夠使用params;promise

注意:雖然op中有了success,error,但添加dataService的時候,儘可能使用promise的處理。緩存

 

代碼示例

經過dataServices的add(factory內置)的方法來註冊數據服務;實現了search和update兩個接口。另一個initOptions是須要對op初始化的是重寫異步

首先註冊一個模擬後臺異步數據服務 - server;只接受params來過濾數據:測試

var dataServices = st.dataServices,
        dataManager = st.dataManager,
        _db = [],
        _cache = [];

    //將params解析成過濾方法
    function buildFilterByParams(params) {
        if (params) {
            return function(item) {
                var check = true;
                $.each(params, function(name, value) {
                    if (item[name] !== value) {
                        check = false;
                        return check;
                    }
                })
                return check;
            }
        }
    }

    //取對象數據,測試使用array只取第一條
    function getData(data) {
        return $.isArray(data) ? data[0] : data;
    }

    function buildFitler(filter) {
        if (filter && typeof filter === 'object') {
            return buildFilterByParams(filter);
        }
        return filter;
    }

    //模擬服務端異步返回數據,只接受params
    dataServices.add("server", {
        search: function(op) {
            //模擬異步查詢
            setTimeout(function() {
                var result,
                    filter = op.filter;

                result = filter ? _db.filter(filter) : _db;

                op.success && op.success(result);
            }, 100);
        },
        update: function(op) {
            //模擬異步更新
            setTimeout(function() {
                var filter = op.filter,
                    data = getData(op.data);

                if (filter) {
                    //測試使用,只更新第一條匹配數據
                    $.each(_db, function(i, item) {
                        if (filter(item)) {
                            _db[i] = data;
                            return false;
                        }
                    })
                } else {
                    _db = op.data || [];
                }

                op.success && op.success(op.data);

            }, 100);
        },
        initOptions: function(op) {
            //初始化設置參數將params編譯成filter過濾方法
            op.filter = buildFilterByParams(op.params);
        }
    });

 

 

而後在註冊一個模擬客戶端取數據的緩存服務服務 - cache,使用filter進行過濾。ui

//模擬客戶端本地存儲
    dataServices.add("cache", {
        search: function(op) {
            var result, filter = op.filter;

            result = filter ? _cache.filter(filter) : _cache;

            op.success && op.success(result);
        },
        update: function(op) {
            var filter = op.filter,
                data = getData(op.data);

            if (filter) {
                //測試使用,只更新第一條匹配數據
                $.each(_cache, function(i, item) {
                    if (filter(item)) {
                        _cache[i] = data;
                        return false;
                    }
                })
            } else {
                _cache = op.data || [];
            }
            op.success && op.success(op.data);
        },
        initOptions: function(op) {
            //生成fitler,當filter爲obj類型時,編譯成fn
            op.filter = buildFitler(op.filter);
        }
    });


看一下server的測試用例,直接使用dataServices對象進行操做,使用dsType來設置具體的數據類型;this

describe('dataServices Test', function() {
        it("update", function(endTest) {
            //更新server的數據
            dataServices.update({
                dsType: 'server',
                data: [{
                    name: 'user1',
                    age: 20
                }, {
                    name: 'user2',
                    age: 30
                }],
                success: function(result) {
                    expect(_db.length).toBe(2);
                    endTest();
                }
            });
        })

        it("search", function(endTest) {
            //從新server的數據
            dataServices.search({
                dsType: 'server',
                params: {
                    name: 'user1'
                },
                success: function(result) {
                    expect(result.length).toBe(1);
                    expect(result[0].age).toBe(20);
                    endTest()
                }
            });

        })
    });


dataManager


 

數據管理器,一樣使用factory構建,可是選用的類型爲'class',需動態初始化;擴展建立dm的方法-ceate和生成filter的方法-buildFilter;

另外在基類中,klassInit,get,set,onHandler,addHandler,fireHandler爲實現方法;其餘的都是接口,須要根據具體的數據管理進行實現;

//數據管理器
    dataManager = st.factory({
        name: "dataManager",
        type: "class",
        proto: {
            //建立dm方法
            create: function(type, op) {},
            //生成fitler方法
            buildFilter: function(filter,conf) {}
        },
        base: {
            klassInit: function(op) {},
            //dm初始化方法
            init: function(op) {},
            //獲取數據
            get: function(conf) {},
            //設置數據
            set: function(conf) {},
            //註冊方法到事件委託,handler委託名稱:get,set,trigger
            onHandler: function(handler, fnName, fn, priority, mode) {},
            //添加事件委託
            addHandler: function() {},
            //執行事件委託
            fireHandler: function(name, args) {},
            //dm內置查詢
            innerSearch: function(op) {},
            //dm內置更新
            innerUpdate: function(op) {},
            //檢查數據是否爲空
            checkEmpty: function(data, conf) {},
            //驗證方法
            validate: function() {},
            //清空方法
            clear: function() {},
            //初始化數據服務配置方法
            setDataSerive : function(config){}
        }
    });

 

添加datamanger示例

添加一個簡單的table類型的數據管理,(注只作測試演示,與真正的datamanger-table不是同一個)

//添加一個簡單的table類型的數據管理
    dataManager.add("Table", {
        init: function() {
            this._data = [];
        },
        //dm內置查詢
        innerSearch: function(conf) {
            var filter = conf ? buildFitler(conf.filter) : null;
            return filter ? this._data.filter(filter) : this._data;
        },
        //dm內置更新
        innerUpdate: function(conf) {
            var isUpdate, _data = this._data,
                data = conf.data,
                updateData, filter;

            conf && (filter = buildFitler(conf.filter));

            if (filter) {
                updateData = getData(data);
                //篩選數據
                _data.forEach(function(item, i) {
                    if (filter(item)) {
                        _data[i] = updateData;
                        isUpdate = true;
                        return false;
                    }
                })
                isUpdate || _data.push(updateData);
            } else {
                this._data = data || [];
            }
            return data;
        },
        //判斷數據是否爲空
        checkEmpty: function(data, conf) {
            return data === undefined || data.length === 0;
        },
        //清空數據
        clear: function() {
            this._data = [];
        }
    });


在來看一下怎麼使用這個dm,下面列子中使用了內置的查詢和更新;

//建立一個tabel的manager
        var dm1 = dataManager.create("Table");

        it("update", function() {
            dm1.innerUpdate({
                data: [{
                    name: 'user1',
                    age: 10
                }]
            });
            expect(dm1._data.length).toBe(1);
            expect(dm1._data[0].name).toBe('user1');
        })

        it("search", function() {
            var result = dm1.innerSearch();
            expect(result.length).toBe(1);
            expect(result[0].name).toBe('user1');
        })

        it("update by filter", function() {
            //找不到匹配的數據,則插入新數據
            dm1.innerUpdate({
                data: {
                    name: 'user3',
                    age: 10
                },
                //方法過濾器
                filter: function(user) {
                    return user.name == 'user3';
                }
            });
            expect(dm1._data.length).toBe(2);
            expect(dm1._data[1].name).toBe('user3');

            //更新數據
            dm1.innerUpdate({
                data: {
                    name: 'user3',
                    age: 40
                },
                //方法過濾器
                filter: function(user) {
                    return user.name == 'user3';
                }
            });

            expect(dm1._data.length).toBe(2);
            expect(dm1._data[1].age).toBe(40);
        })

        it("search by filter", function() {
            var result = dm1.innerSearch({
                //方法過濾器
                filter: function(user) {
                    return user.name == 'user3';
                }
            });
            expect(result.length).toBe(1);
            expect(result[0].age).toBe(40);
        })

        it("search by params", function() {
            var result = dm1.innerSearch({
                //參數過濾器
                filter: {
                    name: 'user3'
                }
            });
            expect(result.length).toBe(1);
            expect(result[0].age).toBe(40);
        })

 

在結合dataService來看個查詢的例子,在這裏使用get操做,而不是innerSearch;get和set這兩個動做都會進入數據管理流程,策略纔會生效。而innerSearch和innerUpdate則是隻查詢dm內部。

在這個例子中,get動做會首先在dm內部查詢,找不到數據,在會進入ds查詢,而後將ds查詢的數據同步到dm中。(詳細的流程見dataManager介紹

 

it("get from ds and update", function(endTest) {
            dm1.clear();
            //首先會在dm內部查詢,找不到數據而後在到server上查詢
            dm1.get({
                //設置數據服務爲server
                dataServices: {
                    dsType: 'server'
                },
                success: function(result) {
                    expect(result).toBeDefined();
                    expect(result[0].name).toBe('user1');
                    expect(dm1._data[0].name).toBe('user1');
                    endTest();
                }
            })
        })

        it("get from ds and no update", function(endTest) {
            dm1.clear();
            dm1.get({
                //設置查詢不更新
                update: false,
                dataServices: {
                    dsType: 'server'
                },
                success: function(result) {
                    expect(dm1._data.length).toBe(0);
                    endTest();
                }
            })
        })


在看一個set的例子:

it("set to ds", function(endTest) {
            //更新到ds
            dm1.set({
                data: [{
                    name: "userUpdate"
                }],
                dataServices: {
                    dsType: 'server'
                },
                success: function(result) {
                    expect(_db.length).toBe(1);
                    expect(_db[0].name).toBe('userUpdate');
                    endTest();
                }
            })

        })

        it("set to ds by params", function(endTest) {
            //根據條件更新到ds,條件同時在dm和ds中生效
            dm1.set({
                data: [{
                    name: "userUpdate"
                }],
                params: {
                    id: 1
                },
                dataServices: {
                    dsType: 'server'
                },
                success: function(result) {
                    expect(_db.length).toBe(2);
                    expect(_db[0].name).toBe('userUpdate');
                    endTest();
                }
            })
        })


下篇詳細介紹策略參數的api和場景分析

更多的例子見請到smartjs的github上查看

相關文章
相關標籤/搜索