AtomDataLoader

class webix.AtomDataLoader()

Atomdataloader mixin

References

mixins
DataDriver(), json().
helpers
ajax(), bind(), isArray(), remote().

Referenced by

components
DataLoader(), DataRecord().
views
property(), template(), toolbar().

External references

Official documentation page.

Code

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
webix.AtomDataLoader={
    $init:function(config){
        //prepare data store
        this.data = {};
        this.waitData = webix.promise.defer();

        if (config)
            this._settings.datatype = config.datatype||"json";
        this.$ready.push(this._load_when_ready);
    },
    _load_when_ready:function(){
        this._ready_for_data = true;

        if (this._settings.url)
            this.url_setter(this._settings.url);
        if (this._settings.data)
            this.data_setter(this._settings.data);
    },
    url_setter:function(value){
        value = webix.proxy.$parse(value);

        if (!this._ready_for_data) return value;
        this.load(value, this._settings.datatype);
        return value;
    },
    data_setter:function(value){
        if (!this._ready_for_data) return value;
        this.parse(value, this._settings.datatype);
        return true;
    },
    //loads data from external URL
    load:function(url,call){
        var details = arguments[2] || null;

        this.callEvent("onBeforeLoad",[]);
        if (typeof call == "string"){    //second parameter can be a loading type or callback
            //we are not using setDriver as data may be a non-datastore here
            this.data.driver = webix.DataDriver[call];
            call = arguments[2];
        } else if (!this.data.driver)
            this.data.driver = webix.DataDriver.json;

        //load data by async ajax call
        //loading_key - can be set by component, to ignore data from old async requests
        var callback = [{
            success: this._onLoad,
            error: this._onLoadError
        }];

        if (call){
            if (webix.isArray(call))
                callback.push.apply(callback,call);
            else
                callback.push(call);
        }

        //proxy
        url = webix.proxy.$parse(url);
        if (url.$proxy && url.load)
            return url.load(this, callback, details);

        //promize
        if (typeof url === "function"){
            return url(details).then(
                webix.bind(function(data){
                    webix.ajax.$callback(this, callback, "", data, -1);
                }, this),
                webix.bind(function(x){
                    webix.ajax.$callback(this, callback, "", null, x, true);
                }, this)
            );
        }

        //normal url
        return webix.ajax(url,callback,this);
    },
    //loads data from object
    parse:function(data,type){
        //[webix.remote]
        if (data && data.then && typeof data.then == "function"){
            return data.then(webix.bind(function(data){
                if (data && typeof data.json == "function")
                    data = data.json();
                this.parse(data, type);
            }, this));
        }

        //loading data from other component
        if (data && data.sync && this.sync)
            return this._syncData(data);

        this.callEvent("onBeforeLoad",[]);
        this.data.driver = webix.DataDriver[type||"json"];
        this._onLoad(data,null);
    },
    _syncData: function(data){
        if(this.data)
            this.data.attachEvent("onSyncApply",webix.bind(function(){
                if(this._call_onready)
                    this._call_onready();
            },this));

        this.sync(data);
    },
    _parse:function(data){
        var parsed, record,
            driver = this.data.driver;

        record = driver.getRecords(data)[0];
        parsed = record?driver.getDetails(record):{};

        if (this.setValues)
            this.setValues(parsed);
        else
            this.data = parsed;
    },
    _onLoadContinue:function(data, text, response, loader){
        if (data){
            if(!this.$onLoad || !this.$onLoad(data, this.data.driver)){
                if(this.data && this.data._parse)
                    this.data._parse(data); //datastore
                else
                    this._parse(data);
            }
        }
        else
            this._onLoadError(text, response, loader);

        //data loaded, view rendered, call onready handler
        if(this._call_onready)
            this._call_onready();

        this.callEvent("onAfterLoad",[]);
        this.waitData.resolve();
    },
    //default after loading callback
    _onLoad:function(text, response, loader){
        var driver = this.data.driver;
        var data;

        if (loader === -1)
            data = driver.toObject(response);
        else{
            //ignore data loading command if data was reloaded
            if(this._ajax_queue)
                this._ajax_queue.remove(loader);
            data = driver.toObject(text, response);
        }

        if(!data || !data.then)
            this._onLoadContinue(data);
        else if(data.then && typeof data.then == "function")
            data.then(webix.bind(this._onLoadContinue, this));
    },
    _onLoadError:function(text, xml, xhttp){
        this.callEvent("onAfterLoad",[]);
        this.callEvent("onLoadError",arguments);
        webix.callEvent("onLoadError", [text, xml, xhttp, this]);
    },
    _check_data_feed:function(data){
        if (!this._settings.dataFeed || this._ignore_feed || !data) return true;
        var url = this._settings.dataFeed;
        if (typeof url == "function")
            return url.call(this, (data.id||data), data);
        url = url+(url.indexOf("?")==-1?"?":"&")+"action=get&id="+encodeURIComponent(data.id||data);
        this.callEvent("onBeforeLoad",[]);
        webix.ajax(url, function(text,xml,loader){
            this._ignore_feed=true;
            var driver = webix.DataDriver.json;
            var data = driver.toObject(text, xml);
            if (data)
                this.setValues(driver.getDetails(driver.getRecords(data)[0]));
            else
                this._onLoadError(text,xml,loader);
            this._ignore_feed=false;
            this.callEvent("onAfterLoad",[]);
        }, this);
        return false;
    }
};

/*
    Abstraction layer for different data types
*/