joosy 0.1.0.RC1 → 0.1.0.RC2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -1
- data/MIT-LICENSE +2 -2
- data/README.md +89 -0
- data/app/assets/javascripts/joosy/core/application.js.coffee +25 -5
- data/app/assets/javascripts/joosy/core/form.js.coffee +212 -22
- data/app/assets/javascripts/joosy/core/helpers.js.coffee +11 -1
- data/app/assets/javascripts/joosy/core/joosy.js.coffee +22 -17
- data/app/assets/javascripts/joosy/core/layout.js.coffee +17 -7
- data/app/assets/javascripts/joosy/core/modules/container.js.coffee +19 -15
- data/app/assets/javascripts/joosy/core/modules/events.js.coffee +10 -9
- data/app/assets/javascripts/joosy/core/modules/filters.js.coffee +16 -12
- data/app/assets/javascripts/joosy/core/modules/log.js.coffee +8 -5
- data/app/assets/javascripts/joosy/core/modules/module.js.coffee +31 -21
- data/app/assets/javascripts/joosy/core/modules/renderer.js.coffee +114 -51
- data/app/assets/javascripts/joosy/core/modules/time_manager.js.coffee +2 -2
- data/app/assets/javascripts/joosy/core/modules/widgets_manager.js.coffee +10 -10
- data/app/assets/javascripts/joosy/core/page.js.coffee +31 -21
- data/app/assets/javascripts/joosy/core/preloader.js.coffee +3 -3
- data/app/assets/javascripts/joosy/core/resource/collection.js.coffee +137 -0
- data/app/assets/javascripts/joosy/core/resource/generic.js.coffee +178 -13
- data/app/assets/javascripts/joosy/core/resource/rest.js.coffee +167 -44
- data/app/assets/javascripts/joosy/core/resource/rest_collection.js.coffee +100 -32
- data/app/assets/javascripts/joosy/core/router.js.coffee +23 -25
- data/app/assets/javascripts/joosy/core/templaters/rails_jst.js.coffee +19 -3
- data/app/assets/javascripts/joosy/core/widget.js.coffee +7 -9
- data/app/assets/javascripts/joosy/preloaders/caching.js.coffee +117 -57
- data/app/assets/javascripts/joosy/preloaders/inline.js.coffee +23 -24
- data/app/helpers/joosy/sprockets_helper.rb +1 -1
- data/lib/joosy/forms.rb +2 -12
- data/lib/joosy/rails/version.rb +1 -1
- data/lib/rails/generators/joosy/templates/app/pages/template.js.coffee +1 -1
- data/lib/rails/generators/joosy/templates/app/resources/template.js.coffee +1 -1
- data/spec/javascripts/joosy/core/form_spec.js.coffee +55 -12
- data/spec/javascripts/joosy/core/layout_spec.js.coffee +1 -1
- data/spec/javascripts/joosy/core/modules/container_spec.js.coffee +0 -1
- data/spec/javascripts/joosy/core/modules/module_spec.js.coffee +1 -1
- data/spec/javascripts/joosy/core/modules/renderer_spec.js.coffee +39 -3
- data/spec/javascripts/joosy/core/modules/time_manager_spec.js.coffee +1 -1
- data/spec/javascripts/joosy/core/page_spec.js.coffee +4 -1
- data/spec/javascripts/joosy/core/resource/collection_spec.js.coffee +84 -0
- data/spec/javascripts/joosy/core/resource/generic_spec.js.coffee +86 -3
- data/spec/javascripts/joosy/core/resource/rest_collection_spec.js.coffee +15 -22
- data/spec/javascripts/joosy/core/resource/rest_spec.js.coffee +27 -4
- data/spec/javascripts/joosy/core/widget_spec.js.coffee +3 -14
- metadata +21 -19
- data/README.rdoc +0 -3
@@ -0,0 +1,137 @@
|
|
1
|
+
#
|
2
|
+
# Basic collection of Resources
|
3
|
+
# Turns JSON array into array of Resources and manages them
|
4
|
+
#
|
5
|
+
# Generally you should not use Collection directly. It will be
|
6
|
+
# automatically created by things like Joosy.Resource.Generic#map
|
7
|
+
# or Joosy.Resource.REST#find.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# class R extends Joosy.Resource.Generic
|
11
|
+
# @entity 'r'
|
12
|
+
#
|
13
|
+
# collection = new Joosy.Resource.Collection(R)
|
14
|
+
#
|
15
|
+
# collection.reset [{foo: 'bar'}, {foo: 'baz'}]
|
16
|
+
# collection.each (resource) ->
|
17
|
+
# resource('foo')
|
18
|
+
#
|
19
|
+
class Joosy.Resource.Collection extends Joosy.Module
|
20
|
+
@include Joosy.Modules.Events
|
21
|
+
|
22
|
+
#
|
23
|
+
# Allows to modify data before it gets stored
|
24
|
+
#
|
25
|
+
# @param [Function] action `(Object) -> Object` to call
|
26
|
+
#
|
27
|
+
@beforeLoad: (action) -> @::__beforeLoad = action
|
28
|
+
|
29
|
+
#
|
30
|
+
# Modelized data storage
|
31
|
+
#
|
32
|
+
data: []
|
33
|
+
|
34
|
+
#
|
35
|
+
# @param [Class] model Resource class this collection will handle
|
36
|
+
#
|
37
|
+
constructor: (@model) ->
|
38
|
+
|
39
|
+
#
|
40
|
+
# Clears the storage and attempts to import given JSON
|
41
|
+
#
|
42
|
+
# @param [Object] entities Entities to import
|
43
|
+
# @param [Boolean] notify Indicates whether to trigger 'changed' event
|
44
|
+
#
|
45
|
+
reset: (entities, notify=true) ->
|
46
|
+
if @__beforeLoad?
|
47
|
+
entities = @__beforeLoad entities
|
48
|
+
|
49
|
+
@data = @modelize entities
|
50
|
+
|
51
|
+
if notify
|
52
|
+
@trigger 'changed'
|
53
|
+
this
|
54
|
+
|
55
|
+
#
|
56
|
+
# Turns Objects array into array of Resources
|
57
|
+
#
|
58
|
+
# @param [Array] collection Array of Objects
|
59
|
+
#
|
60
|
+
modelize: (collection) ->
|
61
|
+
root = @model::__entityName.pluralize()
|
62
|
+
|
63
|
+
if collection not instanceof Array
|
64
|
+
collection = collection?[root.camelize(false)]
|
65
|
+
|
66
|
+
if collection not instanceof Array
|
67
|
+
throw new Error "Can not read incoming JSON"
|
68
|
+
|
69
|
+
collection.map (x) =>
|
70
|
+
@model.create x
|
71
|
+
|
72
|
+
#
|
73
|
+
# Calls callback for each Resource inside Collection
|
74
|
+
#
|
75
|
+
# @param [Function] callback
|
76
|
+
#
|
77
|
+
each: (callback) ->
|
78
|
+
@data.each callback
|
79
|
+
|
80
|
+
#
|
81
|
+
# Gets first resource matching description (see Sugar.js Array#find)
|
82
|
+
#
|
83
|
+
# @param [Function] description Callback matcher
|
84
|
+
#
|
85
|
+
find: (description) ->
|
86
|
+
@data.find description
|
87
|
+
|
88
|
+
#
|
89
|
+
# Gets resource by id
|
90
|
+
#
|
91
|
+
# @param [Integer] id Id to find
|
92
|
+
#
|
93
|
+
findById: (id) ->
|
94
|
+
@data.find (x) -> x('id').toString() == id.toString()
|
95
|
+
|
96
|
+
#
|
97
|
+
# Gets resource by its index inside collection
|
98
|
+
#
|
99
|
+
# @param [Integer] i Index
|
100
|
+
#
|
101
|
+
at: (i) ->
|
102
|
+
@data[i]
|
103
|
+
|
104
|
+
#
|
105
|
+
# Removes resource from collection by its index or by === comparison
|
106
|
+
#
|
107
|
+
# @param [Integer] target Index
|
108
|
+
# @param [Resource] target Resource by itself
|
109
|
+
# @param [Boolean] notify Indicates whether to trigger 'changed' event
|
110
|
+
#
|
111
|
+
remove: (target, notify=true) ->
|
112
|
+
if Object.isNumber target
|
113
|
+
index = target
|
114
|
+
else
|
115
|
+
index = @data.indexOf target
|
116
|
+
if index >= 0
|
117
|
+
result = @data.splice(index, 1)[0]
|
118
|
+
if notify
|
119
|
+
@trigger 'changed'
|
120
|
+
result
|
121
|
+
|
122
|
+
#
|
123
|
+
# Adds resource to collection to given index or to the end
|
124
|
+
#
|
125
|
+
# @param [Resource] element Resource to add
|
126
|
+
# @param [Integer] index Index to add to. If omited will be pushed to the end
|
127
|
+
# @param [Boolean] notify Indicates whether to trigger 'changed' event
|
128
|
+
#
|
129
|
+
add: (element, index=false, notify=true) ->
|
130
|
+
if index
|
131
|
+
@data.splice index, 0, element
|
132
|
+
else
|
133
|
+
@data.push element
|
134
|
+
|
135
|
+
if notify
|
136
|
+
@trigger 'changed'
|
137
|
+
element
|
@@ -1,12 +1,129 @@
|
|
1
|
+
#
|
2
|
+
# Basic data wrapper with triggering
|
3
|
+
#
|
4
|
+
# Example:
|
5
|
+
# class R extends Joosy.Resource.Generic
|
6
|
+
# @entity 'r'
|
7
|
+
#
|
8
|
+
# @beforeLoad (data) ->
|
9
|
+
# data.real = true
|
10
|
+
#
|
11
|
+
# r = R.create {r: {foo: {bar: 'baz'}}}
|
12
|
+
#
|
13
|
+
# r('foo') # {baz: 'baz'}
|
14
|
+
# r('real') # true
|
15
|
+
# r('foo.bar') # baz
|
16
|
+
# r('foo.bar', 'fluffy') # triggers 'changed'
|
17
|
+
#
|
1
18
|
class Joosy.Resource.Generic extends Joosy.Module
|
2
19
|
@include Joosy.Modules.Log
|
3
20
|
@include Joosy.Modules.Events
|
4
21
|
|
22
|
+
#
|
23
|
+
# Sets the data source description (which is NOT required)
|
24
|
+
# This has no use in Generic but is required in any descendant
|
25
|
+
#
|
26
|
+
# @param [mixed] Source can be any type including lambda
|
27
|
+
# If lambda is given resource will not expect direct .create() calls
|
28
|
+
# You'll have to prepare descendant with .at() first
|
29
|
+
#
|
30
|
+
# Example:
|
31
|
+
# Class Y extends Joosy.Resource.Generic
|
32
|
+
# @source 'fluffies'
|
33
|
+
# class R extends Joosy.Resource.Generic
|
34
|
+
# @source -> (path) "/"+path
|
35
|
+
#
|
36
|
+
# r = Y.create{} # will work as expected
|
37
|
+
# r = R.create {} # will raise exception
|
38
|
+
# r = R.at('foo/bar').create {} # will work as expected
|
39
|
+
#
|
40
|
+
@source: (source) -> @__source = source
|
41
|
+
|
42
|
+
#
|
43
|
+
# Required to do some magic like skipping the root node
|
44
|
+
#
|
45
|
+
# @param [String] name Singular name of resource
|
46
|
+
#
|
47
|
+
@entity: (name) -> @::__entityName = name
|
48
|
+
|
49
|
+
#
|
50
|
+
# Sets the collection of current Resource
|
51
|
+
#
|
52
|
+
# @param [Object] klass Class to assign as collection
|
53
|
+
#
|
54
|
+
@collection: (klass) -> @::__collection = -> klass
|
55
|
+
|
56
|
+
#
|
57
|
+
# Default value of resource collection
|
58
|
+
# Will try to seek for EntityNamesCollection
|
59
|
+
# Will fallback to Joosy.Resource.Collection
|
60
|
+
#
|
61
|
+
__collection: ->
|
62
|
+
named = @__entityName.camelize().pluralize() + 'Collection'
|
63
|
+
if window[named] then window[named] else Joosy.Resource.Collection
|
64
|
+
|
65
|
+
#
|
66
|
+
# Allows to modify data before it gets stored
|
67
|
+
#
|
68
|
+
# @param [Function] action `(Object) -> Object` to call
|
69
|
+
#
|
5
70
|
@beforeLoad: (action) -> @::__beforeLoad = action
|
6
71
|
|
7
|
-
|
72
|
+
#
|
73
|
+
# Dynamically creates collection of inline resources
|
74
|
+
# Inline resource share the instance with direct data and therefore can be used
|
75
|
+
# to better handle inline changes
|
76
|
+
#
|
77
|
+
# Example:
|
78
|
+
# class Zombie extends Joosy.Resource.Generic
|
79
|
+
# @entity 'a'
|
80
|
+
# class Puppy extends Joosy.Resource.Generic
|
81
|
+
# @entity 'b'
|
82
|
+
# @maps 'zombies'
|
83
|
+
#
|
84
|
+
# p = Puppy.create {zombies: [{foo: 'bar'}]}
|
85
|
+
#
|
86
|
+
# p('zombies') # Direct access: [{foo: 'bar'}]
|
87
|
+
# p.zombies # Wrapped Collection of Zombie instances
|
88
|
+
# p.zombies.at(0)('foo') # bar
|
89
|
+
#
|
90
|
+
# @param [String] name Pluralized name of property to define
|
91
|
+
# @param [Class] klass Resource class to instantiate
|
92
|
+
#
|
93
|
+
@map: (name, klass=false) ->
|
94
|
+
unless klass
|
95
|
+
klass = window[name.singularize().camelize()]
|
96
|
+
|
97
|
+
if !klass
|
98
|
+
throw new Error "#{Joosy.Module.__className @}> class can not be detected for '#{name}' mapping"
|
99
|
+
|
100
|
+
@beforeLoad (data) ->
|
101
|
+
@[name] = new (klass::__collection()) klass
|
102
|
+
if Object.isArray data[name]
|
103
|
+
@[name].reset data[name]
|
104
|
+
data
|
105
|
+
|
106
|
+
#
|
107
|
+
# Creates the descnendant of current resource with proper source
|
108
|
+
# Should be used together with lambda source (see @source for example)
|
109
|
+
#
|
110
|
+
@at: ->
|
111
|
+
if !Object.isFunction @__source
|
112
|
+
throw new Error "#{Joosy.Module.__className @}> should be created directly (without `at')"
|
113
|
+
|
114
|
+
class clone extends this
|
115
|
+
clone.__source = @__source arguments...
|
116
|
+
clone
|
117
|
+
|
118
|
+
#
|
119
|
+
# Wraps instance of resource inside shim-function allowing to track
|
120
|
+
# data changes. See class example
|
121
|
+
#
|
122
|
+
# @return [Joosy.Resource.Generic]
|
123
|
+
#
|
124
|
+
@create: ->
|
8
125
|
shim = ->
|
9
|
-
shim.__call.apply
|
126
|
+
shim.__call.apply shim, arguments
|
10
127
|
|
11
128
|
if shim.__proto__
|
12
129
|
shim.__proto__ = @prototype
|
@@ -16,22 +133,46 @@ class Joosy.Resource.Generic extends Joosy.Module
|
|
16
133
|
|
17
134
|
shim.constructor = @
|
18
135
|
|
19
|
-
@apply
|
136
|
+
@apply shim, arguments
|
20
137
|
|
21
138
|
shim
|
22
139
|
|
140
|
+
#
|
141
|
+
# Should NOT be called directly, use .create() instead
|
142
|
+
#
|
143
|
+
# @param [Object] data Data to store
|
144
|
+
#
|
23
145
|
constructor: (data) ->
|
24
|
-
@__fillData
|
25
|
-
|
146
|
+
@__fillData data
|
147
|
+
|
148
|
+
#
|
149
|
+
# Getter for wrapped data
|
150
|
+
#
|
151
|
+
# @param [String] path Attribute name to get. Can contain dots to get inline Objects values
|
152
|
+
# @return [mixed]
|
153
|
+
#
|
26
154
|
get: (path) ->
|
27
|
-
target = @__callTarget
|
155
|
+
target = @__callTarget path
|
28
156
|
target[0][target[1]]
|
29
157
|
|
158
|
+
#
|
159
|
+
# Setter for wrapped data, triggers 'changed'
|
160
|
+
#
|
161
|
+
# @param [String] path Attribute name to set. Can contain dots to get inline Objects values
|
162
|
+
# @param [mixed] value Value to set
|
163
|
+
#
|
30
164
|
set: (path, value) ->
|
31
|
-
target = @__callTarget
|
165
|
+
target = @__callTarget path
|
32
166
|
target[0][target[1]] = value
|
33
167
|
@trigger 'changed'
|
168
|
+
null
|
34
169
|
|
170
|
+
#
|
171
|
+
# Locates the actual instance of dotted path from get/set
|
172
|
+
#
|
173
|
+
# @param [String] path Path to the attribute ('foo.bar')
|
174
|
+
# @return [Array] Instance of object containing last step of path and keyword for required field
|
175
|
+
#
|
35
176
|
__callTarget: (path) ->
|
36
177
|
if path.has(/\./) && !@e[path]?
|
37
178
|
path = path.split '.'
|
@@ -46,16 +187,40 @@ class Joosy.Resource.Generic extends Joosy.Module
|
|
46
187
|
else
|
47
188
|
[@e, path]
|
48
189
|
|
190
|
+
#
|
191
|
+
# Wrapper for .create() magic
|
192
|
+
#
|
49
193
|
__call: (path, value) ->
|
50
|
-
if
|
194
|
+
if arguments.length > 1
|
51
195
|
@set path, value
|
52
196
|
else
|
53
197
|
@get path
|
54
198
|
|
55
|
-
|
56
|
-
|
199
|
+
#
|
200
|
+
# Defines how exactly prepared data should be saved
|
201
|
+
#
|
202
|
+
# @param [Object] data Raw data to store
|
203
|
+
#
|
204
|
+
__fillData: (data, notify=true) ->
|
205
|
+
@e = @__prepareData data
|
206
|
+
|
207
|
+
if notify
|
208
|
+
@trigger 'changed'
|
209
|
+
|
210
|
+
null
|
57
211
|
|
58
|
-
|
59
|
-
|
60
|
-
|
212
|
+
#
|
213
|
+
# Prepares raw data: cuts the root node if it exists, runs before filters
|
214
|
+
#
|
215
|
+
# @param [Object] data Raw data to prepare
|
216
|
+
# @return [Object]
|
217
|
+
#
|
218
|
+
__prepareData: (data) ->
|
219
|
+
if Object.isObject(data) && Object.keys(data).length == 1 && @__entityName
|
220
|
+
name = @__entityName.camelize(false)
|
221
|
+
data = data[name] if data[name]
|
222
|
+
|
223
|
+
if @__beforeLoad?
|
224
|
+
data = @__beforeLoad data
|
225
|
+
|
61
226
|
data
|
@@ -1,76 +1,199 @@
|
|
1
1
|
#= require ./rest_collection
|
2
2
|
|
3
|
+
#
|
4
|
+
# Resource with the HTTP REST as the backend
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
# class Rocket extends Joosy.Resource.REST
|
8
|
+
# @entity 'rocket'
|
9
|
+
#
|
10
|
+
# r = Rocket.find {speed: 'fast'} # queries /rockets/?speed=fast to get RESTCollection
|
11
|
+
# r = Rocket.find 1 # queries /rockets/1 to get Rocket instance
|
12
|
+
#
|
13
|
+
# class Engine extends Joosy.Resource.REST
|
14
|
+
# @entity 'engine'
|
15
|
+
# @source ->
|
16
|
+
# (rocket) "/rockets/#{rocket 'id'}/engines"
|
17
|
+
#
|
18
|
+
# e = Engine.at(r).find {oil: true} # queries /rockets/1/engies?oil=true
|
19
|
+
#
|
3
20
|
class Joosy.Resource.REST extends Joosy.Resource.Generic
|
4
21
|
|
22
|
+
#
|
23
|
+
# Default primary key field 'id'
|
24
|
+
#
|
5
25
|
__primaryKey: 'id'
|
6
|
-
|
7
|
-
|
8
|
-
|
26
|
+
|
27
|
+
|
28
|
+
#
|
29
|
+
# Default value of resource collection
|
30
|
+
# Will try to seek for EntityNamesCollection
|
31
|
+
# Will fallback to Joosy.Resource.RESTCollection
|
32
|
+
#
|
33
|
+
__collection: ->
|
34
|
+
named = @__entityName.camelize().pluralize() + 'Collection'
|
35
|
+
if window[named] then window[named] else Joosy.Resource.RESTCollection
|
36
|
+
|
37
|
+
#
|
38
|
+
# Sets the field containing primary key
|
39
|
+
#
|
40
|
+
# It has no direct use inside the REST resource itself and can be omited
|
41
|
+
# That's said: REST resource can work without primary at all. It's here
|
42
|
+
# just to improve end-users experience for cases when primary exists.
|
43
|
+
#
|
44
|
+
# @param [String] primary Name of the field
|
45
|
+
#
|
9
46
|
@primary: (primary) -> @::__primaryKey = primary
|
10
47
|
|
11
|
-
|
12
|
-
|
48
|
+
#
|
49
|
+
# Should NOT be called directly, use .create() instead
|
50
|
+
#
|
51
|
+
# @param [Integer|String|Object] description ID of entity or full data to store
|
52
|
+
#
|
53
|
+
constructor: (description={}) ->
|
54
|
+
if @constructor.__isId description
|
13
55
|
@id = description
|
14
56
|
else
|
15
57
|
super description
|
16
58
|
@id = @e[@__primaryKey]
|
17
59
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
@::__entityName
|
23
|
-
|
24
|
-
# Returns single entity if int/string given
|
60
|
+
#
|
61
|
+
# Queries for REST data and creates resources instances
|
62
|
+
#
|
63
|
+
# Returns single entity if integer or string given
|
25
64
|
# Returns collection if no value or Object (with parameters) given
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
65
|
+
#
|
66
|
+
# If first parameter is a Function it's considered as a result callback
|
67
|
+
# In this case parameters will be considered equal to {}
|
68
|
+
#
|
69
|
+
# Example:
|
70
|
+
# class Rocket extends Joosy.Resource.REST
|
71
|
+
# @entity 'rocket'
|
72
|
+
#
|
73
|
+
# Rocket.find 1
|
74
|
+
# Rocket.find {type: 'nuclear'}, (data) -> data
|
75
|
+
# Rocket.find (data) -> data
|
76
|
+
# Rocket.find 1,
|
77
|
+
# success: (data) -> data)
|
78
|
+
# cache: true
|
79
|
+
#
|
80
|
+
# @param [Integer|String|Object] description ID of entity or full data to store
|
81
|
+
# @param [Function|Object] options AJAX options.
|
82
|
+
# Will be considered as a success callback if function given
|
83
|
+
#
|
84
|
+
# @return [Joosy.Resource.REST|Joosy.Resource.RESTCollection]
|
85
|
+
#
|
86
|
+
@find: (description, options) ->
|
87
|
+
if Object.isFunction options
|
88
|
+
options = {success: options}
|
89
|
+
|
90
|
+
if @__isId description
|
91
|
+
resource = @create description
|
92
|
+
resource.fetch options
|
30
93
|
resource
|
31
94
|
else
|
32
|
-
if Object.isFunction
|
33
|
-
|
95
|
+
if !options? && Object.isFunction description
|
96
|
+
options = {success: description}
|
34
97
|
description = undefined
|
35
|
-
resources = new
|
36
|
-
resources.fetch
|
98
|
+
resources = new (@::__collection()) this, description
|
99
|
+
resources.fetch options
|
37
100
|
resources
|
38
101
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
102
|
+
#
|
103
|
+
# Queries the resource url and reloads the data from server
|
104
|
+
#
|
105
|
+
# @param [Function|Object] options AJAX options.
|
106
|
+
# Will be considered as a success callback if function given
|
107
|
+
# @return [Joosy.Resource.REST]
|
108
|
+
#
|
109
|
+
fetch: (options) ->
|
110
|
+
if Object.isFunction options
|
111
|
+
callback = options
|
112
|
+
else
|
113
|
+
callback = options?.success
|
114
|
+
delete options?.success
|
43
115
|
|
116
|
+
@constructor.__ajax 'get', @constructor.__buildSource(extension: @id), options, (e) =>
|
117
|
+
@__fillData e, false
|
118
|
+
callback? this
|
119
|
+
@trigger 'changed'
|
44
120
|
this
|
45
121
|
|
46
122
|
save: ->
|
47
123
|
|
48
|
-
|
124
|
+
#
|
125
|
+
# Destroys the resource by DELETE query
|
126
|
+
#
|
127
|
+
# @param [Function|Object] options AJAX options.
|
128
|
+
# Will be considered as a success callback if function given
|
129
|
+
# @return [Joosy.Resource.REST]
|
130
|
+
#
|
131
|
+
destroy: (options) ->
|
132
|
+
if Object.isFunction options
|
133
|
+
callback = options
|
134
|
+
else
|
135
|
+
callback = options?.success
|
136
|
+
delete options?.success
|
137
|
+
|
49
138
|
@constructor.__ajax 'delete', @constructor.__buildSource(extension: @id), options, (e) =>
|
50
|
-
callback?
|
51
|
-
|
139
|
+
callback? this
|
52
140
|
this
|
53
|
-
|
54
|
-
|
55
|
-
|
141
|
+
|
142
|
+
#
|
143
|
+
# Requests the REST member URL with POST or any method given in options.type
|
144
|
+
#
|
145
|
+
# @param [String] ending Member url (like 'foo' or 'foo/bar')
|
146
|
+
# @param [Function|Object] options AJAX options.
|
147
|
+
# Will be considered as a success callback if function given
|
148
|
+
#
|
149
|
+
request: (ending, options) ->
|
150
|
+
if Object.isFunction options
|
151
|
+
callback = options
|
152
|
+
else
|
153
|
+
callback = options?.success
|
154
|
+
delete options?.success
|
155
|
+
|
156
|
+
if options.method || options.type
|
157
|
+
type = options.method || options.type
|
158
|
+
else
|
159
|
+
type = 'post'
|
160
|
+
|
161
|
+
@constructor.__ajax type, @constructor.__buildSource(extension: "#{@id}/#{ending}"), options, callback
|
162
|
+
|
163
|
+
#
|
164
|
+
# Checks if given description can be considered as ID
|
165
|
+
#
|
166
|
+
# @param [Integer|String|Object] something Value to test
|
167
|
+
# @return [Boolean]
|
168
|
+
#
|
169
|
+
@__isId: (something) ->
|
170
|
+
Object.isNumber(something) || Object.isString(something)
|
171
|
+
|
172
|
+
#
|
173
|
+
# jQuery AJAX wrapper
|
174
|
+
#
|
175
|
+
# @param [String] method HTTP Method (GET/POST/PUT/DELETE)
|
176
|
+
# @param [String] url URL to query
|
177
|
+
# @param [Object] options AJAX options to pass with request
|
178
|
+
# @param [Function] callback XHR callback
|
179
|
+
#
|
56
180
|
@__ajax: (method, url, options={}, callback) ->
|
57
|
-
$.ajax url,
|
181
|
+
$.ajax url, Joosy.Module.merge options,
|
58
182
|
type: method
|
59
183
|
success: callback
|
60
184
|
cache: false
|
61
185
|
dataType: 'json'
|
62
|
-
).merge options
|
63
186
|
|
187
|
+
#
|
188
|
+
# Builds URL for current resource location
|
189
|
+
#
|
190
|
+
# @param [Object] options Handling options
|
191
|
+
# extension: string to add to resource base url
|
192
|
+
# params: GET-params to add to resulting url
|
193
|
+
#
|
64
194
|
@__buildSource: (options={}) ->
|
65
|
-
unless
|
66
|
-
|
67
|
-
|
68
|
-
source =
|
69
|
-
|
70
|
-
__fillData: (data) ->
|
71
|
-
data = @__prepareData data
|
72
|
-
|
73
|
-
if Object.isObject(data) && data[@constructor.entityName()] && data.keys().length == 1
|
74
|
-
@e = Object.extended data[@constructor.entityName()]
|
75
|
-
else
|
76
|
-
@e = data
|
195
|
+
unless @hasOwnProperty '__source'
|
196
|
+
@__source = "/" + @::__entityName.pluralize()
|
197
|
+
|
198
|
+
source = if Object.isFunction(@__source) then @__source() else @__source
|
199
|
+
source = Joosy.buildUrl "#{source}/#{options.extension || ''}", options.params
|