-
Notifications
You must be signed in to change notification settings - Fork 9
/
index.js
171 lines (150 loc) · 4.22 KB
/
index.js
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
/*
MeteorJS data proxy for Webix
Allows to use Meteor data collections in all places where normal http urls can be used
*/
webix.proxy.meteor = {
$proxy:true,
parseSource:function(){
//decode string reference if necessary
if (typeof this.source == "object"){
if (this.source instanceof Meteor.Collection){
this.collection = this.source;
this.cursor = this.collection.find();
} else if (this.source instanceof Meteor.Collection.Cursor){
this.collection = this.source.collection;
this.cursor = this.source;
}
} else {
//[WARNING] there is no public method to convert collection name to the object
this.cursor = Meteor.connection._mongo_livedata_collections[this.source];
this.collection = this.cursor.collection;
}
},
/*
some.load("meteor->books");
or
some.load( webix.proxy("meteor", Books) )
or
some.load( webix.proxy("meteor", Books->find() ))
or
url:"meteor->ref"
*/
load:function(view, callback){
this.parseSource();
this.query = this.cursor.observe({
//data in meteor collection added
added: function(post) {
//event can be triggered while initial data loading - ignoring
if (view.waitData.state == "pending") return;
//event triggered by data saving in the same component
if (view.meteor_saving) return;
post.id = post._id+"";
delete post._id;
//do not trigger data saving events
webix.dp(view).ignore(function(){
view.add(post);
});
},
//data in meteor collection changed
changed: function(post) {
//event triggered by data saving in the same component
if (view.meteor_saving) return;
var id = post._id+"";
delete post._id;
//do not trigger data saving events
webix.dp(view).ignore(function(){
view.updateItem(id, post);
});
},
//data in meteor collection removed
removed: function(post) {
//event triggered by data saving in the same component
if (view.meteor_saving) return;
//do not trigger data saving events
webix.dp(view).ignore(function(){
view.remove(post._id+"");
});
}
});
//initial data loading
this.cursor.rewind();
var data = this.cursor.fetch();
var result = [];
for (var i=0; i<data.length; i++){
var record = data[i];
record.id = record._id+"";
delete record._id;
result.push(record);
}
webix.ajax.$callback(view, callback, "", result, -1);
},
/*
save:"meteor->ref"
*/
save:function(view, obj, dp, callback){
this.parseSource();
//flag to prevent triggering of onchange listeners on the same component
view.meteor_saving = true;
delete obj.data.id;
if (obj.operation == "update"){
//data changed
this.collection.update(obj.id, { $set: obj.data } );
webix.delay(function(){
callback.success("", { }, -1);
});
} else if (obj.operation == "insert"){
//data added
var id = this.collection.insert(obj.data);
webix.delay(function(){
callback.success("", { newid: id }, -1);
});
} else if (obj.operation == "delete"){
//data removed
this.collection.remove(obj.id);
webix.delay(function(){
callback.success("", {}, -1);
});
}
view.meteor_saving = false;
},
//called when data source is not used anymore
release:function(){
if (this.query)
this.query.stop();
}
};
/*
Helper for component.sync(reference)
*/
webix.attachEvent("onSyncUnknown", function(target, source){
if (window.Meteor && source instanceof Meteor.Collection.Cursor){
var proxy = webix.proxy("meteor", source);
//due to some limitations in Webix 2.2 we can't use above proxy with DataStore directly
//so will create intermediate data collection and use syn like
//meteor -> data collection -> target view
var data = new webix.DataCollection({
url:proxy,
save:proxy
});
target.sync(data);
}
});
webix.protoUI({
name:"reactive",
$init:function(){
this.$ready.push(this.render);
this.$view.className += " webix_selectable ";
this.$view.style.overflow = "auto";
},
render:function(){
this.$view.innerHTML="";
if (this.config.data)
UI.renderWithData(Template[this.config.template], this.config.data, this.$view);
else
UI.render(Template[this.config.template], this.$view);
},
setValue:function(data){
this.config.data = data;
this.render();
}
}, webix.ui.view, webix.BaseBind);