-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathModel.js
126 lines (109 loc) · 2.73 KB
/
Model.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
/* istanbul ignore if */
if (typeof define !== 'function') { var define = require('amdefine')(module); }
define([
'./Class',
'./util/async',
'./util/extend',
'./util/diff',
'./trait/pubsub'
], function(Class, async, extend, diff, pubsub) {
"use strict";
function copy(a) {
if (a != null && typeof a === 'object') {
return Array.isArray(a) ? Array.prototype.slice.call(a) :
a.constructor === Object ? extend({}, a) :
a;
}
return a;
}
function isNumeric(n) {
return !(isNaN(n) || n !== 0 && !n);
}
var dirtyCheck = function(old, novel) {
this._dirty = 0;
diff.call(this, novel || this._data, old, this.trigger);
},
constructor = Class.extend({
init: function(id, data) {
if (isNumeric(id)) {
id = +id;
}
if (data === undefined && typeof id === 'object') {
data = id;
id = undefined;
}
this.get = this.get.bind(this);
this.set = this.set.bind(this);
try {
Object.defineProperties(this, {
_id: {
value: id
},
_dirty: {
value: 0,
writable: true
},
_data: {
enumerable: false,
configurable: true,
value: extend({}, this.default, data),
writable: true
}
});
}
catch (noDefineProperty) {
// Can't use ES5 Object.defineProperty, fallback
this._dirty = 0;
this._data = data || {};
}
},
destroy: function() {
this.stopListening().off();
async.clearImmediate(this._dirty);
this._data = null;
},
id: function() {
return this._id;
},
data: function() {
var orig = this._data, clone;
if (!this._dirty) {
clone = Object.keys(orig).reduce(function(obj, key) {
return obj[key] = copy(orig[key]), obj;
}, {});
this._dirty = async(dirtyCheck.bind(this, clone));
}
return this._data;
},
get: function(prop) {
var value = this._data[prop];
// If getting an array, we must watch for array mutators
if (Array.isArray(value)) {
return this.data()[prop];
}
return value;
},
set: function(values, value) {
var key, data = this.data();
if (typeof values === "string") {
data[values] = copy(value);
return this;
}
if (typeof values === "object") {
for (key in values) {
if (values.hasOwnProperty(key)) {
data[key] = copy(values[key]);
}
}
return this;
}
},
toJSON: function() {
return this._data;
}
}, {
displayName: 'Model'
})
.mixin(pubsub);
return constructor;
});