Kaynağa Gözat

basic-be comm js

jason.lu 6 yıl önce
ebeveyn
işleme
76f585d582

+ 466 - 0
sourcecode/h5app/vue/src/connector/basic-service.js

@@ -0,0 +1,466 @@
+/**
+ *
+ *  Basic
+ *  所有页面的共用基础功能
+ *  //TODO: 文件名可能需要修改
+ *  //TODO: failing ES-Lint
+ *  //TODO: Automated Test
+ *
+ *  dependency:
+ *  jQuery (ajax, selector)
+ *
+ *  @ jason.lu
+ * */
+
+
+function utils_get_param(name){
+    var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
+    var r = window.location.search.substr(1).match(reg);
+    if(r!=null)return  unescape(r[2]); return null;
+}
+
+function reloadPage(){
+    location.reload()
+}
+
+let Queue = {THRESHOLD: 1000,
+    IS_LOADED : false,
+    nowuse : 0, SVR_URL:"http://localhost:8803/server/",
+    groupsCount : 0, groups:[],
+    shouldStop : false,
+    backup:["http://localhost:8803/server/",
+        "/server/",
+        "http://172.30.84.3:8803/server/","https://1.niimei.com/server/"] ,
+    list:[], temporary:0, errorCount:0};
+
+let Users = {list : []};
+let Sectors = {list : []};
+
+function get_server_url() {
+    let output = $.ajax({url: Queue.SVR_URL + "/fcFlow/list", timeout:1000 }).fail(on_check_fail).done(function(){
+        Queue.IS_LOADED = true;
+        console.warn("Using SERVER : ");
+        console.warn(Queue.SVR_URL);
+        setTimeout(parse_queue, 50);
+    });
+}
+
+function on_check_fail(){
+    if(Queue.nowuse === Queue.backup.length - 1){
+        console.warn("Backup Failed : " + Queue.backup[Queue.nowuse]);
+        console.warn(this);
+        var out = "";
+        Queue.backup.forEach(function(val,index,arr){
+            out += val + "\n";
+        });
+        send_alert("抱歉, 服务器连接失败! \n 请确认 " + out + "其中之一可用");
+    }else{
+        Queue.nowuse ++;
+        Queue.SVR_URL = Queue.backup[Queue.nowuse];
+        $.ajax({url: Queue.SVR_URL + "/fcFlow/list", timeout:1000 }).fail(on_check_fail).done(function(){
+            Queue.IS_LOADED = true;
+            console.warn("Using SERVER : ");
+            console.warn(Queue.SVR_URL);
+            setTimeout(parse_queue, 50);
+        });
+    }
+}
+
+function get_data(url, callback, scope) {
+    Queue.list.push({url:url, callback:callback, gid:-1, scope:scope});
+}
+
+function new_data_group(groupName, callback){
+    var gid = -1;
+    Queue.groups.forEach(function(val,index,arr){
+        if(val.groupName === groupName){
+            gid = val.gid;
+        }
+    });
+    if(gid === -1) {
+        gid = Queue.groupsCount;
+        Queue.groupsCount++;
+        Queue.groups.push({
+            gid: gid, groupName:groupName, callme: callback, counter:0
+        });
+    }
+    return gid;
+}
+
+function group_get_data(groupName, url, callback){
+    var gid = -1;
+    Queue.groups.forEach(function(val,index,arr){
+        if(val.groupName === groupName){
+            gid = val.gid;
+        }
+    });
+    if(gid === -1) {
+        send_alert("Group 方法使用错误!!!")
+    }
+    Queue.list.push({url:url, callback:callback, gid:gid});
+}
+
+function parse_queue(){
+    console.log("Queue Length : " + Queue.list.length);
+
+    if(Queue.temporary > new Date().getTime()){
+        for(i = 0; i < Queue.list.length; i++) {
+            Queue.list.pop();
+        }
+    }
+
+    Queue.temporary = 0;
+
+    if(Queue.list.length > 0){
+        let one = Queue.list.pop();
+        if(one.gid === -1) {
+            request_data(one.url, one.callback, one.scope);
+        }else{
+            g_request_data(one.url, one.callback, one.gid, one.scope);
+        }
+    }
+    if(Queue.shouldStop == false) {
+        setTimeout(parse_queue, 50);
+    }
+}
+
+function request_data(url, callback, scope){
+    $.ajax({
+        url: Queue.SVR_URL + url,
+        apiName: url,
+        sendTime: new Date(),
+        callme: callback,
+        callerThis: scope
+    }).done(on_dat_success).fail(on_fail);
+}
+
+function g_request_data(url, callback, gid){
+    $.ajax({
+        url: Queue.SVR_URL + url,
+        apiName: url,
+        sendTime: new Date(),
+        gid: gid,
+        callme: callback
+    }).done(on_gp_success).fail(on_fail);
+}
+
+function on_gp_success(a,b) {
+    var gid = this.gid;
+    if(check_if_success(a,b)) {
+        this.callme(a,b);
+        Queue.groups.forEach(function(v,i,a){
+            if(v.gid === gid){
+                v.counter ++;
+                v.callme(v);
+            }
+        });
+    }
+}
+
+function on_dat_success(a,b){
+    if(check_if_authfail(a,b)){
+        setCookieWithTimeout("doibyUser","",-10);
+        location.href = "sign-in1.html?from=entrance-5&msg=server-redirect-detected";
+        return;
+    }
+    if(check_if_success(a,b)) {
+        this.callme(a,b);
+    }
+}
+
+function check_if_authfail(a){
+    if(a == null || typeof a !== "string") {
+        return false;
+    }else{
+        if(a.indexOf("login?from=") > 0 || a.startsWith("<!DOCTYPE html>") || a.indexOf("<!-- SME::LOGINPAGE -->") > 0){
+            return true;
+        }
+    }
+    return false;
+}
+
+function check_if_success(a,b){
+    if(typeof a === "string"){
+        try {
+            a = JSON.parse(a);
+        }catch (e) {
+            console.warn("=----------   异常   -----------=");
+            console.warn(a);
+            console.warn("=----------------------------=");
+            send_alert("信息失败 : "+e);
+            return;
+        }
+    }else if(typeof a === "undefined"){
+        console.warn("=----------   异常   -----------=");
+        console.warn(a);
+        console.warn("=------------------------------=");
+        send_alert("信息失败 : "+e);
+        return;
+    }
+    if(a.ret === "10000") {
+        return true;
+    }else{
+        console.trace();
+        console.error(b);
+        console.error(JSON.stringify(a));
+        send_alert("查询失败 : 请参阅控制台输出! ");
+    }
+
+    return false;
+}
+
+function on_fail(msg, sta) {
+    Queue.errorCount += 1;
+    if(Queue.errorCount >= 10){
+        Queue.errorCount = 0;
+        Queue.temporary = new Date().getTime() + 30*1000;
+        Queue.shouldStop = true;
+        console.warn("-----  Too many failure, temporary stop HTTP ------");
+        send_alert("很抱歉,网络错误数量过多,暂时终止HTTP功能30s");
+    }
+    let vurl = "";
+    try {
+        vurl = " : "+this.url.substring(7, 12);
+    }catch (e) {
+        vurl = "";
+    }
+    send_alert("很抱歉,网络错误,请查看 Console" + vurl);
+    console.warn("-----   网络请求失败 ---------");
+    try {
+        console.warn(JSON.stringify(this));
+    }catch (e) {
+        console.warn(JSON.stringify(this.url));
+        console.warn(JSON.stringify(this.responseText));
+    }
+    console.warn("-----------msg-------------");
+    console.warn(JSON.stringify(msg));
+    console.warn("-----------sta--------------");
+    console.warn(JSON.stringify(sta));
+    console.warn("----------------------------");
+}
+
+function first_parse(ajax, obj) {
+    if (typeof obj === "string") {
+        obj = JSON.parse(obj);
+    }
+
+    if (typeof obj !== "object") {
+        console.warn(ajax);
+        throw "Error ! Parsing JSON failed ." + JSON.stringify(obj);
+    }
+
+    if (obj.ret === "10000") {
+        return obj.model;
+    } else {
+        console.warn(ajax);
+        throw "Error ! Server returned error." + JSON.stringify(obj);
+    }
+}
+
+
+function on_document_load() {
+    if(typeof (page_document_load) !== "undefined"){
+        page_document_load();
+    }
+    if(typeof (resizeAll) !== "undefined"){
+        resizeAll();
+    }
+}
+
+var AlertClosingTimeout = 0;
+
+function send_alert(a, b){
+
+    if(Queue.shouldStop) return;
+    $("#mpAlert").html(a);
+    $("#mpAlert").show();
+
+    if(AlertClosingTimeout > 0) {
+        clearTimeout(AlertClosingTimeout);
+    }
+
+    AlertClosingTimeout = setTimeout(function(){
+        if ($("#mpAlert").html().indexOf("<") >= 0) {
+            return;
+        }
+        $("#mpAlert").hide();
+    }, 10000);
+
+    return;
+
+    var q = "<!-- Modal 部分开始 -->\n<div class=\"modal fade\" id=\"alertModal\" tabindex=\"-1\" role=\"dialog\" aria-hidden=\"true\">\n    <div class=\"modal-dialog\" role=\"document\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <h5 class=\"modal-title\" id=\"alertModalLabel\">New message</h5>\n                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n                    <span aria-hidden=\"true\">&times;</span>\n                </button>\n            </div>\n            <div class=\"modal-body\">\n                <form>\n                    <div class=\"form-group\">\n                        <label for=\"recipient-name\" class=\"col-form-label\">Recipient:</label>\n                        <input type=\"text\" class=\"form-control\" id=\"recipient-name\">\n                    </div>\n                    <div class=\"form-group\">\n                        <label for=\"message-text\" class=\"col-form-label\">Message:</label>\n                        <textarea class=\"form-control\" id=\"message-text\"></textarea>\n                    </div>\n                </form>\n            </div>\n            <div class=\"modal-footer\">\n                <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close</button>\n                <button type=\"button\" class=\"btn btn-primary\">Send message</button>\n            </div>\n        </div>\n    </div>\n</div>";
+    //var model = document.createElement("div");
+    if($("#modalContainer").length <= 0){
+        alert(a);
+        return ;
+    }
+    $("#modalContainer").html(q);
+    var modalO = $("alertModal");
+    if(modalO.length === 0){
+        alert(a);
+    }else{
+        $("#alertModelLabel").text(b);
+        $("#message-text").text(b);
+        modalO.modal('show');
+    }
+
+}
+
+function getUserName(uid){
+    var uname = null;
+    Users.list.forEach(function(val, aid, arr){
+        if(val.worker.staffId === uid){
+            uname = val.worker.staffName;
+        }
+    });
+    if(uname == null) {
+        if(uid != 0) {
+            get_data("oaStaff/list?staffId=" + uid, on_username_retn);
+            return "[用户:"+uid+"]";
+        } else return "[用户:"+uid+"]";
+    }else{
+        return uname;
+    }
+}
+
+function on_username_retn(obj, sta) {
+    var uid = this.url.substring(this.url.indexOf("staffId=") + 8);
+    let ruid = parseInt(uid);
+    var out = first_parse(this, obj);
+    if(out.list.length > 0){
+        Users.list.push({
+            uid : ruid, worker: out.list[0]
+        });
+    }
+}
+
+function getSectorName(sectorId){
+    var secName = null;
+    Sectors.list.forEach(function(val, aid, arr){
+        if(val.sector.sectorId === sectorId){
+            secName = val.sector.sectorName;
+        }
+    });
+    if(secName == null) {
+        get_data("fcSector/list?sectorId=" + sectorId, on_secname_retn);
+        return "[工位:"+sectorId+"]";
+    }else{
+        return secName;
+    }
+}
+
+function on_secname_retn(obj, sta) {
+    var secid = this.url.substring(this.url.indexOf("sectorId=") + 9);
+    let rsecid = parseInt(secid);
+    var out = first_parse(this, obj);
+    if(out.list.length > 0){
+        Sectors.list.push({
+            secid : rsecid, sector: out.list[0]
+        });
+    }
+}
+
+function getSectorId(spotId){
+    var secId = null;
+    Sectors.list.forEach(function(val, aid, arr){
+        if(val.sector.spotId === spotId){
+            secId = val.sector.sectorId;
+        }
+    });
+    if(secId == null) {
+        get_data("fcSectorSpot/list?spotId=" + spotId, on_secid_retn);
+        return -1;
+    }else{
+        return secId;
+    }
+}
+
+function on_secid_retn(obj, sta) {
+    var spotId = this.url.substring(this.url.indexOf("spotId=") + 7);
+    let rsecid = parseInt(spotId);
+    var out = first_parse(this, obj);
+    if(out.list.length > 0){
+        Sectors.list.push({
+            secid : rsecid, sector: out.list[0]
+        });
+    }
+}
+
+/**
+ *  Calc b/a+b * 100(precision = 2), when b is zero, return zero
+ * @param a (pass)
+ * @param b (fail)
+ */
+function get_factor(a,b){
+    if(a+b === 0){
+        return 0;
+    }else{
+        return Math.floor(10000* b / (a+b) ) / 100;
+    }
+}
+
+function setCookieWithTimeout(name, value, liveMinutes) {
+    if (liveMinutes == undefined || liveMinutes == null) {
+        liveMinutes = 60 * 2;
+    }
+    if (typeof (liveMinutes) != 'number') {
+        liveMinutes = 60 * 2;//默认120分钟
+    }
+    var minutes = liveMinutes * 60 * 1000;
+    var exp = new Date();
+    exp.setTime(exp.getTime() + minutes + 8 * 3600 * 1000);
+    //path=/表示全站有效,而不是当前页
+    document.cookie = name + "=" + value + ";path=/;expires=" + exp.toUTCString();
+}
+
+function setCookie(c_name,value,expiredays)
+{
+    var exdate=new Date()
+    exdate.setDate(exdate.getDate()+expiredays)
+    document.cookie=c_name+ "=" +escape(value)+
+        ((expiredays==null) ? "" : ";expires="+exdate.toGMTString())
+}
+
+function getCookie(c_name)
+{
+    if (document.cookie.length>0)
+    {
+        c_start=document.cookie.indexOf(c_name + "=")
+        if (c_start!=-1)
+        {
+            c_start=c_start + c_name.length+1
+            c_end=document.cookie.indexOf(";",c_start)
+            if (c_end==-1) c_end=document.cookie.length
+            return unescape(document.cookie.substring(c_start,c_end))
+        }
+    }
+    return "";
+}
+
+var userId = utils_get_param("userId");
+
+function getUserId() {
+    console.log("Original  USERID : " + userId);
+    var use = getCookie("doibyUser");
+    if (use == null || use === undefined || use.length <= 0) {
+        location.href = "sign-in1.html?from=entrance-1&msg=nologin-mustauth";
+        return;
+    }
+    console.log("Got UID From COOKIE : " + use);
+    try{
+        var mm = parseInt(use);
+        if(mm <= 0){
+        }else{
+            userId = mm;
+        }
+    }catch (e) {
+        location.href = "sign-in1.html?from=entrance-1&msg=cookie-wrong-format";
+        return;
+    }
+
+    console.log("Got UserId Eventually : " + userId);
+}
+
+
+$(document).ready(on_document_load);
+get_server_url();

+ 243 - 0
sourcecode/h5app/vue/src/connector/data-object.js

@@ -0,0 +1,243 @@
+/***
+ * Data Object Related helper classes (vue applicable)
+ * dependency:
+ *
+ * jQuery (ajax, selector)
+ */
+
+const DEFAULT = 2;
+const ONDEMAND = 4;
+const AUTO = 8;
+const FAST = 16;
+const PASSIVE = 32;
+
+
+/***
+ * DataObject DO
+ * @param cname
+ * @param serverJsonObj
+ * @constructor
+ */
+var DataObject = function(cname, serverJsonObj){
+    this.ctlName = cname;
+    this.jsonObj = serverJsonObj;
+    this.getVal = function (key, obj) {
+        return obj.jsonObj[key];
+    };
+    this.serVal = function (key, val, obj) {
+        obj.jsonObj[key] = val;
+    };
+
+};
+
+/***
+ * DataObjectList
+ * @param name
+ * @constructor
+ */
+var DataObjectList = function(name){
+    this.ctlName = name;
+    this.list = null;
+    this.isSorted = false;
+    this.preSort = [];
+    /***
+     * sorting
+     * @param comparator (a,b)  =====>  a - b
+     */
+    this.sortBy = function(comparator){
+        this.preSort = new Array();
+        for (let i = 0; i < this.list.length; i++) this.preSort.push(this.list[i]);
+        this.quickSort(this.preSort, 0, this.preSort.length - 1, comparator);
+    };
+
+    this.clearData = function () {
+        this.isSorted = false;
+        this.preSort = null;
+        this.list = null;
+    }
+
+    this.len = function() {
+        if(this.list == null) return 0;
+        return this.list.length;
+    };
+
+    this.mergeJsonData = function (data) {
+        this.list = new Array();
+        for (let i = 0; i < data.length; i++) this.addObject(data[i]);
+    };
+
+    this.addObject = function (jsonObj) {
+        this.list.push(new DataObject(this.ctlName, jsonObj));
+    };
+
+    this.assignJsonData = function (data) {
+        this.clearData();
+        this.mergeJsonData(data);
+    };
+    this.getRaw = function (index) {
+        if(this.list == null) return null;
+        return this.list[index];
+    };
+    this.getSorted = function (index) {
+        if(this.list == null) return null;
+        if(!this.isSorted) return this.getRaw(index);
+        return this.preSort[index];
+    };
+    this.quickSort = function (a,left,right,comp){
+        if(left>right){ //一定要有这个判断,因为有递归left和i-1,若没有这个判断条件,该函数会进入无限死错位递归
+            return;
+        }
+
+        var i=left,
+            j=right,
+            pivot=a[left]; //基准总是取序列开头的元素
+
+        while(i!=j){
+            while((comp(a[j],pivot) > 0)&&i<j){j--}
+            while((comp(a[j],pivot) <= 0)&&i<j){i++}
+            if(i<j){  //如果i==j跳出外层while
+                var t=a[i];
+                a[i]=a[j];
+                a[j]=t;
+            }
+        }
+
+        a[left]=a[i];//交换基准数和k位置上的数
+        a[i]=pivot;
+
+        this.quicksort(a,left,i-1,comp);
+        this.quicksort(a,i+1,right,comp);
+    };
+};
+
+/***
+ * DOService
+ * @param controlName
+ * @constructor
+ */
+var DataObjectService = function(controlName, syncType, extparm){
+    this.ctlName    = controlName;
+    // 2=default 4=on-demand, 8=auto, 16:fast, 32=passive
+    this.syncType   = syncType;
+    this.extParm    = extparm;
+    this.isDefault  =  ((syncType & DEFAULT)  !== 0);
+    this.isOnDemand = ((syncType & ONDEMAND)  !== 0);
+    this.isAuto =     ((syncType & AUTO)  !== 0);
+    this.isFast =     ((syncType & FAST) !== 0);
+    this.isPassive  = ((syncType & PASSIVE) !== 0);
+    this.failedCount= 0;
+    this.list       = new DataObjectList(controlName);
+    this.autoUpdateTimer = 0;
+    this.autoInterval = 1000;
+    this.callerThis = this;
+
+    this.setUpInterval = function() {
+        //URL + exparm
+        if(this.autoUpdateTimer != 0) clearInterval(this.autoUpdateTimer);
+        this.autoUpdateTimer = setInterval(this.selfUpdateTick, this.autoInterval, this);
+        setTimeout(this.selfUpdateTick, 1000, this);
+    }
+
+    this.init = function(){
+        this.appUrl = controlName + "/list" + extparm;
+        if(!this.isFast || this.isOnDemand){
+            this.autoInterval = 300;
+        }
+
+        if(this.isFast) {
+            this.appUrl = controlName + "/get" + extparm;
+        }
+
+        if(this.isAuto){
+            // timer
+            this.setUpInterval();
+        }
+    };
+
+    this.stopTimers = function () {
+        clearInterval(this.autoUpdateTimer);
+        this.autoUpdateTimer = 0;
+    };
+
+    /***
+     * Automatica Update Tick, where obj is a replacement for "this" where "this" might be incorrect
+     * @param obj : DataObjectService
+     */
+    this.selfUpdateTick = function(obj){
+        get_data(obj.appUrl, obj.onDataReceived, obj);
+    };
+
+    this.onDemandUpdate = function(obj){
+        get_data(obj.appUrl, obj.onDataReceived, obj);
+    };
+
+    this.onDataReceived = function(data, sta){
+        let obj = this.callerThis;
+        if(obj == undefined){console.error("Cannot get callerThis in onDataReceived, please check"); console.error(this)}
+        let output = first_parse(this, data);
+        if (output.list == undefined || output.list.length == 0) {
+            obj.failedCount++;
+            if(obj.failedCount > 100){
+                obj.failedCount = 0;
+                obj.stopTimers();
+                console.log("[排行榜返回为空git clone https://github.com/pentaho/mondrian-tck.git次数过多],暂停刷新");
+            }
+            if(obj.failedCount == 2) {
+                send_alert("排行榜多次返回没有数据,请尝试重新加载! [" + obj.appUrl +"]");
+            }
+        }else{
+            obj.list.assignJsonData(output.list);
+        }
+    };
+
+    this.getList = function () {
+        return this.list;
+    };
+
+    this.passiveUpdate = function(data){
+        this.failedCount = 0;
+        this.list.assignJsonData(data);
+    };
+
+    this.init();
+};
+
+var SinglePage = function () {
+    this.modules = [];
+};
+
+var Module = function(chartContainerSelector, dataCtlName){
+    this.selector = chartContainerSelector;
+    this.dataCtl = dataCtlName;
+    this.activeData = null;
+    this.lastActive = 0;
+    this.tickInterval = 1000;
+    /***
+     * bindData to UI
+     * @param data DataObjectList
+     */
+    this.setData = function (data) {
+        if(data.ctlName == this.dataCtl){
+            console.log(`-------- Module ${this.selector} got data ----------- `);
+            this.activeData = data;
+            this.drawData(this.activeData);
+        }else{
+            console.log(`-------- Module ${this.selector} cannot use data of ${data.ctlName} ----------- `);
+        }
+    };
+    this.init = function () {
+        // do init
+        this.setupInterval();
+    };
+    this.tick = function () {
+        // do tick
+    };
+    this.setupInterval = function () {
+        // do tick
+        if(this.tickInterval != 0) clearInterval(this.tickInterval);
+        this.tickInterval = setInterval(this.tick, this.tickInterval);
+    };
+    this.drawData = function () {
+        // do drawData
+    };
+};

+ 110 - 0
sourcecode/h5app/vue/src/connector/simple-demo.js

@@ -0,0 +1,110 @@
+/*****
+ *
+ * Assuming a HTML like
+ *
+ * <... id="test-app-1">
+ *     <... v-for="oneuser in userlist">
+ *         {{oneuser.id}} , name: {{oneuser.name}}
+ *     </...>
+ *
+ * </...>
+ *
+ */
+var test_vue_app = new Vue({
+    el : "test-app-1",
+    data : {
+        userlist : [{id:1, name:"hello"}]
+    }
+});
+
+ /******************************************************************************
+ //
+ // To load directly from JS(jQuery)
+ //
+ /*****************************************************************************/
+
+function js_load_something(){
+    var uid = 5; //for test.
+    get_data("smartUsers/list"+"?userId="+uid,
+        /**
+         * 下面的function是访问网络成功后的结果回调,obj 类似
+         *
+         * http://south.niimei.com:8866/server/smartUsers/list
+         * {
+         *   "ret":"10000","detail":null,"field":null,"model":
+         *   {"page":1,"pageSize":15,"totalPage":1,"totalResult":15,
+         *    "list":
+         *      [
+         *        {
+         *       "uid":3,"usn":"cell_13520583918","pss":"64e604787cbf194841e7b68d7cd28786f6c9a0a3ab9f8b0a0e87cb4387ab0107",
+         *       "name":"HelloWorld","title":"","priv":"view,order,deliver,pay","state":0,"sess":"iOgxGPkFIV3JxBlBfCv",
+         *       "phone":"13520583918","schoolDistrict":null,"userExpPts":null,"userGroup":null,"userVcoin":null,"registerTime":null,
+         *       "lastLoginTime":null,"wxUnionid":null,"wxEngineid":null,"wxOpenid":null,"note":null
+         *        },
+         *        {..第二条数据..},
+         *        {..第三条数据..}
+         *      ]
+         *    }
+         * }
+         * @param obj
+         */
+        function (obj) {
+            var parsedObj = first_parse(this, obj);
+            if(parsedObj != null && parsedObj != undefined) {
+                test_vue_app = parsedObj.list;
+            } else {
+                // error
+            }
+        } //end of f (obj, status)
+    ); // end of get_data
+}
+
+
+/******************************************************************************
+ //
+ // To load using DataObject + DataService + Module stuff
+ //
+ *****************************************************************************/
+
+var test_vue_module = new Module("nothing", "smartUsers");
+test_vue_module.drawData = function (data) {
+    test_vue_app.data.userlist.pop();
+    for(let i = 0; i < data.len(); i++) {
+        test_vue_app.data.userlist.push(data.getSorted(i));
+    }
+} ;
+
+var loader = new (function(){
+
+    this.userListServ = new DataObjectService("smartUsers", AUTO, "");
+
+    // Optional for setting up self-defined interval
+    // this.userListServ.autoInterval = 300;
+    // this.userListServ.setUpInterval();
+
+    /**
+     * load Once, as is.
+     */
+    this.loadOnce = function(){
+        var list = this.userListServ.list;
+        test_vue_module.setData(list);
+    };
+
+    /***
+     * loadOften : to auto-load some data
+     */
+    this.loadOften = function(){
+        // Intervals
+        this.userListServ.bind(function (data) {
+            // auto call
+            test_vue_module.setData(data);
+        });
+    };
+})();
+
+//To load once
+loader.loadOnce();
+
+//To auto-refresh
+// loader.loadOften();
+