rails_jskit 5.0.0 → 5.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +494 -112
- data/lib/generators/jskit/install/install_generator.rb +0 -11
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad1c775799b28a7db824596cc46bd3a408e4dfe4
|
4
|
+
data.tar.gz: 5705864e3a14dfc72b20cd65bceee5efb1c09107
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57bc99de58e79d624bfbc3b3b98ed98d29bb60189df8aeed45bcf7df6e5be5c0f1b7688fe4c343dd5e6a329b8e5cd0d9d9731c7d46240550a2321a9978bbb1a3
|
7
|
+
data.tar.gz: 8f7c5caba135044cf229c8b43e7e8b916e258ce782e6a5307ee9109c4142f8e291a22ca80c61a88207aa7d0dcd1efa6908af4d8f51d7399ec9a369dfbaf23a49
|
data/README.md
CHANGED
@@ -3,214 +3,596 @@
|
|
3
3
|
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/rails_jskit.svg)](http://badge.fury.io/rb/rails_jskit)
|
5
5
|
|
6
|
-
rails_jskit is a gem that let's you seamlessly integrate rails with [JSkit](https://github.com/daytonn/jskit). View the example repo [here](https://github.com/daytonn/rails_jskit-example)
|
7
|
-
|
8
|
-
[Documentation](http://daytonn.github.io/rails_jskit/documentation.html)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
rails_jskit is a gem that let's you seamlessly integrate rails with [JSkit](https://github.com/daytonn/jskit). View the example repo [here](https://github.com/daytonn/rails_jskit-example).
|
7
|
+
|
8
|
+
* [Online Documentation](http://daytonn.github.io/rails_jskit/documentation.html)
|
9
|
+
* [Dependencies](#dependencies)
|
10
|
+
* [Installation](#installation)
|
11
|
+
- [Automatic Installation](#automatic-installation)
|
12
|
+
- [Manual Installation](#manual-installation)
|
13
|
+
* [Documentation](#getting-started)
|
14
|
+
- [Application Object](#application-object)
|
15
|
+
* [Dispatcher](#dispatcher)
|
16
|
+
* [Controllers Object](#controllers-object)
|
17
|
+
* [Controller Factories](#controller-factories)
|
18
|
+
- [Controllers](#controllers)
|
19
|
+
* [Actions](#actions)
|
20
|
+
* [Mapped Actions](#mapped-actions)
|
21
|
+
* [The `all` Action](#the-all-action)
|
22
|
+
* [Creating an Application Controller](#creating-an-application-controller)
|
23
|
+
* [Passing Data To Actions](#passing-data-to-actions)
|
24
|
+
* [Elements](#elements)
|
25
|
+
* [Events](#events)
|
26
|
+
|
27
|
+
* [Configuration](#configuration)
|
28
|
+
* [Testing](#getting-started)
|
29
|
+
- [Controller Factories](#controller-factories)
|
30
|
+
- [Testing Actions](#testing-actions)
|
31
|
+
- [Testing Elements](#testing-elements)
|
32
|
+
- [Testing Events](#testing-events)
|
33
|
+
|
34
|
+
Dependencies
|
35
|
+
------------
|
13
36
|
|
14
|
-
|
37
|
+
RailsJskit requires `jquery` (or equivalent) and `lodash` (or equivalent). Require them in your `app/assets/javascripts/application.js` before `//= require rails_jskit`.
|
15
38
|
|
16
39
|
```js
|
40
|
+
// app/assets/javascripts/application.js
|
17
41
|
//= require lodash
|
18
42
|
//= require jquery
|
19
43
|
```
|
20
44
|
|
21
|
-
-- or --
|
22
|
-
|
23
|
-
```js
|
24
|
-
//= require underscore
|
25
|
-
//= require zepto
|
26
|
-
```
|
27
|
-
|
28
45
|
Installation
|
29
46
|
------------
|
30
47
|
|
31
48
|
Add `rails_jskit` to your Gemfile:
|
32
49
|
|
33
|
-
```
|
50
|
+
```ruby
|
51
|
+
# Gemfile
|
34
52
|
gem "rails_jskit"
|
35
53
|
```
|
36
54
|
|
37
|
-
Bundle it up
|
55
|
+
Bundle it up
|
38
56
|
|
39
57
|
```sh
|
40
58
|
bundle install
|
41
59
|
```
|
42
60
|
|
43
|
-
|
44
|
-
-----
|
61
|
+
###Automatic Installation
|
45
62
|
|
46
|
-
|
63
|
+
RailsJskit comes with handy generators to get you started quickly. Use the generator to install jskit:
|
47
64
|
|
48
|
-
```
|
49
|
-
|
65
|
+
```sh
|
66
|
+
rails generate jskit:install
|
50
67
|
```
|
51
68
|
|
52
|
-
|
69
|
+
Or you can install it the good old-fashioned way, by hand:
|
70
|
+
|
71
|
+
###Manual Installation
|
72
|
+
|
73
|
+
Create a `app/assets/javascripts/controllers/` directory and add rails_jskit to `app/assets/javascripts/application.js`:
|
53
74
|
|
54
75
|
```js
|
76
|
+
// app/assets/javascripts/application.js
|
77
|
+
...
|
55
78
|
//= require rails_jskit
|
79
|
+
//= require_tree ./controllers
|
80
|
+
```
|
81
|
+
|
82
|
+
Add `jskit` to your application layout:
|
83
|
+
|
84
|
+
```erb
|
85
|
+
# app/views/layouts/application.html.erb
|
86
|
+
<!DOCTYPE html>
|
87
|
+
<html>
|
88
|
+
<head>
|
89
|
+
<title>JskitExample</title>
|
90
|
+
<%= stylesheet_link_tag 'application', media: 'all' %>
|
91
|
+
<%= csrf_meta_tags %>
|
92
|
+
</head>
|
93
|
+
<body>
|
94
|
+
<%= yield %>
|
95
|
+
<%= javascript_include_tag 'application' %>
|
96
|
+
<%= jskit %>
|
97
|
+
</body>
|
98
|
+
</html>
|
56
99
|
```
|
57
100
|
|
58
|
-
That's it
|
101
|
+
**That's it!** You're ready to use RailsJskit.
|
102
|
+
|
103
|
+
Now all your controllers will be loaded at runtime but nothing will execute until events are dispatched.
|
104
|
+
|
105
|
+
Documentation
|
106
|
+
-------------
|
107
|
+
|
108
|
+
### Application Object
|
109
|
+
|
110
|
+
RailsJskit will automatically create a JSkit application object for you, using the configured `app_namespace` for the global variable name _(defaults to "App")_. This global namespace provides you a way to interact with your JSkit application. You can #{link_to "configure", "#configuration"} this setting in your initializer `(config/initializers/rails_jskit.rb)`.
|
111
|
+
|
112
|
+
#### Dispatcher
|
113
|
+
|
114
|
+
Every JSkit application has a `Dispatcher` object. This object is responsible for registering and triggering events in your application. In general you don't interact directly with the application's Dispatcher, though it's important to know what it is and what it's doing. By default, every controller created by your application will have it's own reference to the Dispatcher object. A controller's actions will automatically be registered on the Dispatcher when it's created, so you shouldn't need to interact with the Dispatcher directly.
|
115
|
+
|
116
|
+
#### Controllers Object
|
117
|
+
|
118
|
+
Every JSkit application also has a `Controllers` object that stores the Controllers instantiated by your application at runtime. Everytime you create a controller, an instance is created on the controllers object:
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
|
122
|
+
// app/assets/javascripts/controllers/posts_controller.js
|
123
|
+
App.createController("Posts", {
|
124
|
+
...
|
125
|
+
});
|
126
|
+
|
127
|
+
App.Controllers.Posts;// Instantiated Posts controller object
|
128
|
+
```
|
129
|
+
|
130
|
+
#### Controller Factories
|
131
|
+
|
132
|
+
In addition to instances of each controller, the factory used to create the controller is stored on the application object itself. The factory is a function that will create a freshly initialized controller, useful in testing environments:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
|
136
|
+
// app/assets/javascripts/controllers/posts_controller.js
|
137
|
+
App.createController("Posts", {
|
138
|
+
...
|
139
|
+
});
|
140
|
+
|
141
|
+
App.PostsController;// Factory function to create fresh Posts controller objects
|
142
|
+
```
|
59
143
|
|
60
144
|
### Controllers
|
61
145
|
|
62
|
-
JSkit
|
146
|
+
The basic component of JSkit is the Controller. Controllers allow you to coordinate JavaScript execution with your Rails controllers. For example, assuming you have a `PostsController` in `app/controllers/posts_controller.rb`.
|
63
147
|
|
64
|
-
```
|
65
|
-
|
148
|
+
```ruby
|
149
|
+
# app/controllers/posts_controller.rb
|
150
|
+
class PostsController < ApplicationController
|
151
|
+
def index
|
152
|
+
render :index
|
153
|
+
end
|
154
|
+
end
|
66
155
|
```
|
67
156
|
|
68
|
-
|
157
|
+
#### Actions
|
158
|
+
|
159
|
+
To define JavaScript for that controller, create a corresponding JSkit controller in `app/assets/javascripts/controllers/posts_controller.js` and define it's `actions`. The actions array tells JSkit which functions you want automatically wired to the controller's events. If you wish to run javascript on the `index` action of the `PostsController`, it would look something like this:
|
69
160
|
|
70
161
|
```js
|
71
|
-
|
162
|
+
// app/assets/javascripts/controllers/posts_controller.js
|
163
|
+
App.createController("Posts", {
|
164
|
+
actions: ["index"]
|
165
|
+
|
166
|
+
index: function() {
|
167
|
+
// behavior for posts#index
|
168
|
+
}
|
169
|
+
});
|
72
170
|
```
|
73
171
|
|
74
|
-
|
172
|
+
Now whenever your `PostsController` renders the `index` action, the JSkit controller's index method will execute. It's that simple.
|
173
|
+
|
174
|
+
#### Mapped Actions
|
175
|
+
|
176
|
+
You may find yourself wanting to wire up an action with a different function name than it's corresponding rails controlller, or you may want to assign the same function to multiple actions. This can be acheived by using a mapped action:
|
75
177
|
|
76
|
-
|
178
|
+
```js
|
179
|
+
// app/assets/javascripts/controllers/posts_controller.js
|
180
|
+
App.createController("Posts", {
|
181
|
+
actions: [{
|
182
|
+
edit: "setupForm",
|
183
|
+
create: "setupForm",
|
184
|
+
update: "setupform"
|
185
|
+
}],
|
186
|
+
|
187
|
+
...
|
188
|
+
setupForm: function() {
|
189
|
+
// form setup
|
190
|
+
}
|
191
|
+
...
|
192
|
+
});
|
193
|
+
```
|
194
|
+
|
195
|
+
This will wire the three events `controllers:posts:edit`, `controllers:posts:create`, and `controllers:posts:upate` to the `setupForm` function.
|
196
|
+
|
197
|
+
This simple convention is flexible enough to accomplish any sane JavaScript task for a given action.
|
198
|
+
|
199
|
+
_Note: you can mix and match objects and strings within the actions array but it's probably best to define the string actions first and pass an object as the last item in the array. This is only for readability as JSkit does not care about the position of the actions in the array._
|
77
200
|
|
78
201
|
```js
|
79
|
-
|
80
|
-
|
81
|
-
|
202
|
+
...
|
203
|
+
actions: [
|
204
|
+
"index",
|
205
|
+
"show",
|
206
|
+
{
|
207
|
+
edit: "setupForm",
|
208
|
+
create: "setupForm",
|
209
|
+
update: "setupForm"
|
210
|
+
}
|
211
|
+
]
|
82
212
|
```
|
83
213
|
|
84
|
-
|
214
|
+
#### The `all` action
|
85
215
|
|
86
|
-
|
216
|
+
There are times when you want a bit of JavaScript to run for every action of a given controller. In this case you can define an `all` method on the controller which will automatically be triggered on every action of the controller:
|
87
217
|
|
88
|
-
|
218
|
+
```js
|
219
|
+
...
|
220
|
+
all: function() {
|
221
|
+
console.log("Happens on every action");
|
222
|
+
}
|
223
|
+
...
|
224
|
+
```
|
225
|
+
|
226
|
+
_Note: you don't have to add `all` to the actions array, JSkit knows what you mean._
|
227
|
+
|
228
|
+
#### Creating an Application Controller
|
229
|
+
|
230
|
+
In some cases, you may want some JavaScript to run on every single page of your application. Something like fading out flash notifications, or instantiating dynamic menus or something of that nature. In this case you can create an Application Controller at: `app/assets/javscripts/controllers/application_controller.js`
|
89
231
|
|
90
232
|
```js
|
233
|
+
// app/assets/javscripts/controllers/application
|
91
234
|
App.createController("Application", {
|
92
235
|
all: function() {
|
93
|
-
|
236
|
+
setTimeout(function() {
|
237
|
+
$("#notifications").fadeOut();
|
238
|
+
}, 3000);
|
239
|
+
|
240
|
+
$("#menu").menuify();
|
94
241
|
}
|
95
242
|
});
|
96
243
|
```
|
97
244
|
|
98
|
-
|
245
|
+
There is nothing special about this controller except the fact that RailsJskit will trigger the `controller:application:all` event on every action of every controller. Which means that the `all` method will execute on every page.
|
246
|
+
|
247
|
+
#### Passing Data To Actions
|
248
|
+
|
249
|
+
Sometimes you may find yourself wanting to pass data from the Rails side of your application to the client side. The JSkit event system accounts for this and RailsJskit provides a simple interface to this functionality. JSkit has three payload methods, which are available to your application's controllers. The three methods correspond to the three levels of triggered events on any given page.
|
99
250
|
|
100
|
-
|
251
|
+
1. `set_app_payload` (sent with "controllers:application:all")
|
252
|
+
2. `set_controller_payload` (sent with "controllers:[controller name]:[action name]")
|
253
|
+
3. `set_action_payload` (sent with "controllers:[controller name][action name]")
|
254
|
+
|
255
|
+
Let's assume you want to pass devise's `current_user` object to the application controller. For this you would use `app_payload`
|
256
|
+
|
257
|
+
```ruby
|
258
|
+
# app/controllers/application_controller.rb
|
259
|
+
class ApplicationController < ActionController::Base
|
260
|
+
before_action :jskit_app_payload
|
261
|
+
|
262
|
+
private
|
263
|
+
|
264
|
+
def jskit_app_payload
|
265
|
+
set_app_payload(current_user)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
```
|
269
|
+
|
270
|
+
This will pass the `current_user` as JSON in the `controllers:application:all` event:
|
101
271
|
|
102
272
|
```js
|
273
|
+
App.Dispatcher.trigger("controller:application:all", { email: "user@example.com", first_name: "John", last_name: "Smith"... });
|
274
|
+
```
|
275
|
+
|
276
|
+
Your application controller can make use of this data by assigning the argument to the action function:
|
277
|
+
|
278
|
+
```js
|
279
|
+
// app/assets/javascripts/controllers/application_controller.js
|
280
|
+
App.createController("Application", {
|
281
|
+
all: function(currentUser) {
|
282
|
+
App.currentUser = currentUser;// { email: "user@example.com", first_name: "John", last_name: "Smith"... }
|
283
|
+
}
|
284
|
+
});
|
285
|
+
```
|
286
|
+
|
287
|
+
These payload methods will take any number of arguments and pass them in order to the event handler. This allows for a simple but flexible way to pass data to your client-side application.
|
288
|
+
|
289
|
+
The `set_controller_payload` method and the `set_action_payload` work in the same way only they pass data to their specific events.
|
290
|
+
|
291
|
+
```ruby
|
292
|
+
# app/controllers/posts_controller.rb
|
293
|
+
class PostsController < ApplicationController
|
294
|
+
before_action :jskit_controller_payload
|
295
|
+
|
296
|
+
def index
|
297
|
+
set_action_payload("Data from the PostsController#index action")
|
298
|
+
end
|
299
|
+
|
300
|
+
private jskit_controller_payload
|
301
|
+
|
302
|
+
def jskit_controller_payload
|
303
|
+
set_controller_payload("Data from the PostsController")
|
304
|
+
end
|
305
|
+
end
|
306
|
+
```
|
307
|
+
|
308
|
+
This data can be accessed in the JSkit controller like so:
|
309
|
+
|
310
|
+
```js
|
311
|
+
// app/assets/javascript/controllers/posts_controller.js
|
103
312
|
App.createController("Posts", {
|
104
313
|
actions: ["index"],
|
105
|
-
|
106
|
-
|
107
|
-
|
314
|
+
|
315
|
+
all: function(message) {
|
316
|
+
console.log(message);// "Data from the PostsController"
|
317
|
+
},
|
318
|
+
|
319
|
+
index: function(message) {
|
320
|
+
console.log(message);// "Data from the PostsController#index action"
|
108
321
|
}
|
109
322
|
});
|
110
323
|
```
|
111
324
|
|
112
|
-
|
325
|
+
#### Elements
|
113
326
|
|
114
|
-
|
327
|
+
It's guaranteed you'll end up saving a reference to an `HTMLElement` wrapped in `jQuery` _(the proverbial jQuery burrito)_. You do this so often, it really helps to have a shorthand for doing so. Consider the following code:
|
115
328
|
|
116
|
-
|
329
|
+
```js
|
330
|
+
// app/assets/controllers/posts_controller.js
|
331
|
+
App.createController("Posts", {
|
332
|
+
actions: ["index"],
|
333
|
+
|
334
|
+
cacheElements: function() {
|
335
|
+
this.$postList = $("ul#posts");
|
336
|
+
this.$commentToggleLink = $("a.comment-toggle");
|
337
|
+
this.$modalWindow = $("#modal-window");
|
338
|
+
this.$modalCloseButton = $("#modal-window-close");
|
339
|
+
},
|
340
|
+
|
341
|
+
index: function() {
|
342
|
+
this.cacheElements();
|
343
|
+
// do stuff with elements
|
344
|
+
}
|
345
|
+
});
|
346
|
+
```
|
347
|
+
|
348
|
+
This is generally pretty clean code. It's easy to read and it's simple. The problem is that we're going to want to do the same thing in other actions. We can use the same `cacheElements` method but we may not need all the selectors.
|
349
|
+
|
350
|
+
If we do want to scope elements to actions, we'll need a way to scope the selected elements to specific actions. JSkit allows you to define this behavior with a simple `elements` object on the controller. Which looks something like this:
|
117
351
|
|
118
352
|
```js
|
353
|
+
// app/assets/controllers/posts_controller.js
|
119
354
|
App.createController("Posts", {
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
355
|
+
elements: {
|
356
|
+
index: {
|
357
|
+
postList: "ul#posts",
|
358
|
+
commentToggleLink: "a.comment-toggle",
|
359
|
+
modalWindow: "#modal-window",
|
360
|
+
modalCloseButton: "#modal-window-close"
|
361
|
+
}
|
362
|
+
},
|
363
|
+
|
127
364
|
index: function() {
|
128
|
-
// do stuff
|
365
|
+
// do stuff with elements
|
366
|
+
}
|
367
|
+
});
|
368
|
+
```
|
369
|
+
|
370
|
+
This keeps all the DOM selection one simple structure that cuts down on the clutter.
|
371
|
+
|
372
|
+
_Note: all keys under each action will be set as variables prefixed with the `$` to indicate that it's a `jQuery` wrapped set._
|
373
|
+
|
374
|
+
The above example would create three variables on the controller object when the `index` action is triggered:
|
375
|
+
|
376
|
+
```js
|
377
|
+
// app/assets/controllers/posts_controller.js
|
378
|
+
App.createController("Posts", {
|
379
|
+
elements: {
|
380
|
+
index: {
|
381
|
+
postList: "ul#posts",
|
382
|
+
commentToggleLink: "a.comment-toggle",
|
383
|
+
modalWindow: "#modal-window",
|
384
|
+
modalCloseButton: "#modal-window-close"
|
385
|
+
}
|
129
386
|
},
|
130
|
-
|
131
|
-
|
132
|
-
|
387
|
+
|
388
|
+
index: function() {
|
389
|
+
this.$postList;
|
390
|
+
this.$commentToggleLink;
|
391
|
+
this.$modalWindow;
|
392
|
+
this.$modalCloseButton;
|
133
393
|
}
|
134
394
|
});
|
135
395
|
```
|
136
396
|
|
137
|
-
|
397
|
+
#### Events
|
138
398
|
|
139
|
-
|
399
|
+
Another common piece of boilerplate code is registering for events on `jQuery` wrapped elements. You know, the meat and potatoes of js development. JSkit has a novel way of tidying up event registration as well. An action's elements can be wired up to event handler functions (defined on the controller) by adding them to the element key's value as an array (tuple):
|
140
400
|
|
141
401
|
```js
|
402
|
+
// app/assets/controllers/posts_controller.js
|
142
403
|
App.createController("Posts", {
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
404
|
+
elements: {
|
405
|
+
index: {
|
406
|
+
launchModalButton: ["#launch-modal", { click: "openModalWindow" }],
|
407
|
+
modalCloseButton: ["#modal-window-close", { click: "closeModalWindow" }]
|
408
|
+
}
|
147
409
|
},
|
148
|
-
|
149
|
-
|
410
|
+
|
411
|
+
openModalWindow: function() {
|
412
|
+
this.$modalWindow.removeClass("hidden");
|
413
|
+
},
|
414
|
+
|
415
|
+
closeModalWindow: function() {
|
416
|
+
this.$modalWindow.addClass("hidden");
|
417
|
+
}
|
150
418
|
});
|
151
419
|
```
|
152
420
|
|
153
|
-
This
|
421
|
+
This is a simple way reduce some of the repetetive code in your everyday JavaScript. It's also tested in JSkit itself, so you don't need to test that the events were registered properly.
|
154
422
|
|
155
|
-
|
423
|
+
_Note: if you are not doing anything else in an action but wiring elements and events, you can skip adding the action to the `actions` array, and creating a function for that action._
|
156
424
|
|
157
|
-
|
425
|
+
##### Multiple Events
|
158
426
|
|
427
|
+
It is also possible to register multiple events on a given element, to do so simply add event keys to the event object for the given action:
|
159
428
|
|
160
|
-
```
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
429
|
+
```js
|
430
|
+
// app/assets/javscripts/controllers/posts_controller.js
|
431
|
+
App.createController("Posts", {
|
432
|
+
elements: {
|
433
|
+
index: {
|
434
|
+
nameField: ["input#name", {
|
435
|
+
change: "handleNameFieldChange",
|
436
|
+
keyup: "handleNameFieldKeyup"
|
437
|
+
}]
|
438
|
+
}
|
439
|
+
},
|
440
|
+
|
441
|
+
handleNameFieldChange: function(evnt) {
|
442
|
+
// handle name field change
|
443
|
+
},
|
444
|
+
|
445
|
+
handleNameFieldKeyup: function(evnt) {
|
446
|
+
// handle name field keyup
|
447
|
+
}
|
448
|
+
});
|
172
449
|
```
|
173
450
|
|
174
|
-
|
451
|
+
Configuration
|
452
|
+
-------------
|
175
453
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
private
|
183
|
-
|
184
|
-
def set_jskit_payload
|
185
|
-
set_app_payload(current_user, [1, 2, 3], { some: "hash" })
|
186
|
-
end
|
454
|
+
At this point, RailsJskit only has one setting, the `app_namespace`. If you're fine with the default namespace of `App`, you don't need to change it. Otherwise create an initializer:
|
455
|
+
|
456
|
+
```ruby
|
457
|
+
# config/initializers/rails_jskit.rb
|
458
|
+
RailsJskit.configure do |config|
|
459
|
+
config.app_namespace = "MyApp"
|
187
460
|
end
|
188
461
|
```
|
189
462
|
|
190
|
-
|
463
|
+
Now you can refer to your application globally as `MyApp`.
|
191
464
|
|
192
465
|
```js
|
193
|
-
|
194
|
-
|
195
|
-
...
|
466
|
+
// app/assets/javascripts/controllers/application_controller.js
|
467
|
+
MyApp.createController("Posts", {...});
|
196
468
|
```
|
197
469
|
|
198
|
-
|
470
|
+
Testing
|
471
|
+
-------
|
199
472
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
473
|
+
One of the main advantages of RailsJSkit is that it provides a simple structure that's easily tested. There are however, a few things you need to keep in mind while testing JSkit controllers.
|
474
|
+
|
475
|
+
When testing, it's important to use the #{link_to "Controller Factories", "#controller-factories"} to create your test subjects. This ensures that you always have a fresh version of the controller that has not been mutated by previous tests. A basic jasmine/mocha style JSkit controller test looks something like this:
|
476
|
+
|
477
|
+
```js
|
478
|
+
// spec/javscripts/controllers/posts_controller_spec.js
|
479
|
+
describe("PostsController", function() {
|
480
|
+
var subject;
|
481
|
+
beforeEach(function() {
|
482
|
+
subject = App.PostsController.create();// creates a fresh controller
|
483
|
+
});
|
484
|
+
|
485
|
+
describe("#index", function() {
|
486
|
+
it("has tests", function() {
|
487
|
+
expect(true).to.equal(true);
|
488
|
+
});
|
489
|
+
});
|
490
|
+
});
|
491
|
+
```
|
492
|
+
|
493
|
+
### Testing Actions
|
494
|
+
|
495
|
+
Testing actions is straight-forward, since they are just functions on your controller object, you can simply call them and test their behavior:
|
496
|
+
|
497
|
+
```js
|
498
|
+
// app/assets/javscripts/controller/posts_controller.js
|
499
|
+
App.createController("Posts", {
|
500
|
+
actions: ["index"],
|
501
|
+
|
502
|
+
elements: {
|
503
|
+
index: {
|
504
|
+
pageContainer: "#container",
|
505
|
+
}
|
506
|
+
},
|
507
|
+
|
508
|
+
index: function(color) {
|
509
|
+
this.color = color;
|
510
|
+
this.$pageContainer.css("background-color", this.color);
|
511
|
+
}
|
512
|
+
});
|
513
|
+
```
|
514
|
+
|
515
|
+
```js
|
516
|
+
// spec/javscripts/controllers/posts_controller_spec.js
|
517
|
+
describe("PostsController", function() {
|
518
|
+
var subject;
|
519
|
+
beforeEach(function() {
|
520
|
+
subject = App.PostsController.create();
|
521
|
+
});
|
522
|
+
|
523
|
+
describe("#index", function() {
|
524
|
+
it("sets the color variable with the given value", function() {
|
525
|
+
subject.index("#FF0000");
|
526
|
+
expect(subject.color).to.equal("#FF0000");
|
527
|
+
});
|
528
|
+
|
529
|
+
it("changes the page background color to the given color", function() {
|
530
|
+
subject.index("#FF0000");
|
531
|
+
expect(subject.$pageContainer.css("background-color")).to.equal("#FF0000");
|
532
|
+
});
|
533
|
+
});
|
534
|
+
});
|
535
|
+
```
|
536
|
+
|
537
|
+
Obviously this is a contrived example but you can see that testing an action is as simple as testing a function.
|
538
|
+
|
539
|
+
### Testing Elements
|
540
|
+
|
541
|
+
While you don't have to test the functionality of JSkit itself, you may want to assert that a certain action has access to a given element. To do this we can simply test the values in the elements object, without having to add fixtures to the test DOM:
|
542
|
+
|
543
|
+
```js
|
544
|
+
// spec/javscripts/controllers/posts_controller_spec.js
|
545
|
+
describe("PostsController", function() {
|
546
|
+
var subject;
|
547
|
+
beforeEach(function() {
|
548
|
+
subject = App.PostsController.create();
|
549
|
+
});
|
550
|
+
|
551
|
+
describe("#index", function() {
|
552
|
+
describe("elements", function() {
|
553
|
+
it("saves a reference to the #container element", function() {
|
554
|
+
expect(subject.elements.index.pageContainer).to.equal("#container");
|
555
|
+
});
|
556
|
+
});
|
557
|
+
});
|
558
|
+
});
|
214
559
|
```
|
215
560
|
|
216
|
-
|
561
|
+
### Testing Events
|
562
|
+
|
563
|
+
Testing events is just as easy as testing elements:
|
564
|
+
|
565
|
+
```js
|
566
|
+
// app/assets/javscripts/controllers/posts_controller.js
|
567
|
+
App.createController("Posts", {
|
568
|
+
elements: {
|
569
|
+
index: {
|
570
|
+
expandCommentsButton: ["#expand-comments", {
|
571
|
+
click: "handleExpandCommentsClick"
|
572
|
+
}]
|
573
|
+
}
|
574
|
+
},
|
575
|
+
|
576
|
+
handleExpandCommentsClick: function() {
|
577
|
+
...
|
578
|
+
}
|
579
|
+
});
|
580
|
+
```
|
581
|
+
|
582
|
+
```js
|
583
|
+
// spec/javscripts/controllers/posts_controller_spec.js
|
584
|
+
describe("PostsController", function() {
|
585
|
+
var subject;
|
586
|
+
beforeEach(function() {
|
587
|
+
subject = App.PostsController.create();
|
588
|
+
});
|
589
|
+
|
590
|
+
describe("#index", function() {
|
591
|
+
describe("events", function() {
|
592
|
+
it("wires up `handleExpandCommentsClick` on click of the $expandCommentsButton", function() {
|
593
|
+
expect(subject.events.index.expandCommentsButton[1].click).to.equal("handleExpandCommentsClick");
|
594
|
+
});
|
595
|
+
});
|
596
|
+
});
|
597
|
+
});
|
598
|
+
```
|
@@ -77,17 +77,6 @@ module Jskit
|
|
77
77
|
"app/assets/javascripts/application.js"
|
78
78
|
end
|
79
79
|
|
80
|
-
def add_js_to_manifest
|
81
|
-
if File.exists? js_manifest
|
82
|
-
if has_jquery?
|
83
|
-
insert_into_file js_manifest, "//= require lodash\n", before: "//= require jquery\n" unless has_lodash?
|
84
|
-
else
|
85
|
-
append_to_file js_manifest, "//= require lodash\n//= require jquery\n"
|
86
|
-
end
|
87
|
-
append_to_file js_manifest, "//= require rails_jskit\n//= require_tree ./controllers\n"
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
80
|
private
|
92
81
|
|
93
82
|
def application_js
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_jskit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.
|
4
|
+
version: 5.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dayton Nolan
|
@@ -28,14 +28,14 @@ dependencies:
|
|
28
28
|
name: appraisal
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|