-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackbone-viewstate.js
120 lines (103 loc) · 3.43 KB
/
backbone-viewstate.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
// for jshint
/*global require, define */
(function(root, factory) {
// Start with AMD support.
if (typeof define === 'function' && define.amd) {
define(['underscore', 'backbone'], function(_, Backbone) {
factory(root, _, Backbone);
});
// Next check for Node.js or CommonJS.
} else if (typeof exports !== 'undefined') {
var _ = require('underscore');
var Backbone = require('backbone');
factory(root, _, Backbone);
// Finnaly, if none of the above, create the extension and
// assume Backbone is available at (browser) global scope.
} else {
factory(root, root._, root.Backbone);
}
}(this, function(root, _, Backbone) {
// Backbone.ViewState
// ------------------
// `Backbone.ViewState` objects are designed to be nothing more but
// a wrapper that is not a Model but does need to 'hold' data.
// An example of a ViewState value is when your mouse or finger
// is hovering over some target to add `{over: true}` to the viewState.
// The idea behind it is that you can use getAttributes as default
// for data in your render function.
// For example:
//
// render: function() {
// this.el.html(template(_.extend(
// this.viewState.getAttributes(),
// this.model.toJSON()
// )));
// }
//
var ViewState = Backbone.ViewState = function(attributes) {
var attrs = attributes || {};
this.attributes = _.clone(attrs);
};
_.extend(ViewState.prototype, Backbone.Events, {
// get the value of an attribute
get: function(attr) {
return this.attributes[attr];
},
// returns all attributes (like toJSON, but this already is 'pojo')
getAttributes: function() {
return _.clone(this.attributes);
},
// Set a hash of attributes on the object (firing `change`). This is
// the core operation of a viewState object, updating the data and
// notifying anyone who needs to know about the change.
set: function(key, val, options) {
var attrs, attr, current, silent, unset, changes = [];
if (key === null) {
return this;
}
// Like in Backbone.Model, you can supply both `{key: value}` as
// `"key", value`-style arguments.
if (typeof key === 'object') {
attrs = key;
options = val;
} else {
(attrs = {})[key] = val;
}
options || (options = {});
unset = options.unset;
silent = options.silent;
current = this.attributes;
for (attr in attrs) {
val = attrs[attr];
if (!_.isEqual(current[attr], val)) {
changes.push(attr);
}
if (unset) {
delete current[attr];
} else {
current[attr] = val;
}
}
if (!silent) {
for (var i = 0, l = changes.length; i < l; i++) {
this.trigger('change:'+ changes[i], this, current[changes[i]], options);
}
this.trigger('change', this, options);
}
return this;
},
// Remove an attribute from the object, also firing a `change`.
unset: function(attr, options) {
return this.set(attr, void 0, _.extend({}, options, {unset: true}));
},
// Clear all attributes off this model, also firing `change`
clear: function(options) {
var attrs = {};
for (var key in this.attributes) {
attrs[key] = void 0;
}
return this.set(attrs, _.extend({}, options, {unset: true}));
}
});
return Backbone.ViewState;
}));