volt 0.4.14 → 0.4.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Readme.md +70 -10
- data/VERSION +1 -1
- data/lib/volt/controllers/model_controller.rb +16 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1b1635ef6a0d61f2fd334870249bffd6a032a55
|
4
|
+
data.tar.gz: 761fe764d63b32d5ce1e65b482b4094d4a4f12fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8c3e07939e8f5f22104bb0e16f30fa4dfb5270741341d31239aa0d4c746089134545a6cfc4214da7915fd6581d191113a8c0560bfee5f3b10c225242a9db17f
|
7
|
+
data.tar.gz: 6fcd81d3d469133e8552869c03a86ca1be4902608e5f825ce580c98716e5a4e8d72be35afafb0aad99097195abf16f6a73e49f03fa94bc08190a91d3377a8696
|
data/Readme.md
CHANGED
@@ -62,6 +62,7 @@ You can access the volt console with:
|
|
62
62
|
|
63
63
|
1. [Rendering](#rendering)
|
64
64
|
1. [Reactive Values](#reactive-values)
|
65
|
+
1. [ReactiveValue Gotchyas](#reactivevalue-gotchyas)
|
65
66
|
2. [Bindings](#bindings)
|
66
67
|
1. [Content Binding](#content-binding)
|
67
68
|
2. [If Binding](#if-binding)
|
@@ -70,6 +71,7 @@ You can access the volt console with:
|
|
70
71
|
2. [Models](#models)
|
71
72
|
1. [Reactive Models](#reactive-models)
|
72
73
|
2. [Model Events](#model-events)
|
74
|
+
3. [Provided Collections](#provided-collections)
|
73
75
|
3. [Components](#components)
|
74
76
|
1. [Assets](#assets)
|
75
77
|
2. [Component Generator](#component-generator)
|
@@ -166,6 +168,20 @@ Lastly, we can also pass in other reactive value's as arguments to methods on a
|
|
166
168
|
# => C changed
|
167
169
|
```
|
168
170
|
|
171
|
+
### ReactiveValue Gotchya's
|
172
|
+
|
173
|
+
There are a few simple things to keep in mind with ReactiveValue's. In order to make them mostly compatible with other ruby objects, a two methods do not return another ReactiveValue.
|
174
|
+
|
175
|
+
to_s and inspect
|
176
|
+
|
177
|
+
If you want these to be used reactively, see the section on [with](#with)
|
178
|
+
|
179
|
+
Also, due to a small limitation in ruby, ReactiveValue's always are truthy. See the [truthy checks](#truthy-checks-true-false-or-and-and) section on how to check for truth.
|
180
|
+
|
181
|
+
### Current Status
|
182
|
+
|
183
|
+
NOTE: currently ReactiveValue's are not complete. At the moment, they do not handle methods that are passed blocks (or procs, lambda's). This is planned, but not complete. At the moment you can use [with](#with) to accomplish similar things.
|
184
|
+
|
169
185
|
### Truthy Checks: .true?, .false?, .or, and .and
|
170
186
|
|
171
187
|
Because a method on a reactive value always returns another reactive value, and because only nil and false are false in ruby, we need a way to check if a ReactiveValue is truthy in our code. The easiest way to do this is by calling .true? on it. It will return a non-wrapped boolean. .nil? and .false? do as you would expect.
|
@@ -189,7 +205,16 @@ Simply use:
|
|
189
205
|
|
190
206
|
### With
|
191
207
|
|
192
|
-
|
208
|
+
Normally when you want to have some a value that depends on another value, but transforms it somehow, you simply call your transform method on the ReactiveValue. However sometimes the transform is not directly on the ReactiveValue's object.
|
209
|
+
|
210
|
+
You can call .with on any ReactiveValue. .with will return a new ReactiveValue that depends on the current ReactiveValue. .with takes a block, the first argument to the block will be the cur value of the ReactiveValue you called with on. Any additional arguments to with will be passed in after the first one. If you pass another ReactiveValue as an argument to .with, the returned ReactiveValue will depend on the argument ReactiveValue as well, and the block will receive the arguments cur value.
|
211
|
+
|
212
|
+
```ruby
|
213
|
+
a = ReactiveValue.new(5)
|
214
|
+
b = a.with {|v| v + 10 }
|
215
|
+
b.cur
|
216
|
+
# => 15
|
217
|
+
```
|
193
218
|
|
194
219
|
## Bindings
|
195
220
|
|
@@ -311,7 +336,9 @@ You can also append to a model if its not defined yet.
|
|
311
336
|
|
312
337
|
An array model will automatically be setup to contain the items appended.
|
313
338
|
|
314
|
-
|
339
|
+
## Provided Collections
|
340
|
+
|
341
|
+
Above I mentioned that Volt comes with many default collection models accessable from a controller. Each stores in a different location.
|
315
342
|
|
316
343
|
| Name | Storage Location |
|
317
344
|
|-----------|---------------------------------------------------------------------------|
|
@@ -331,6 +358,7 @@ Because all models provided by Volt are wrapped in a ReactiveValue, you can regi
|
|
331
358
|
|
332
359
|
Models trigger events when their data is updated. Currently models emit three events: changed, added, and removed. For example:
|
333
360
|
|
361
|
+
```ruby
|
334
362
|
model = Model.new
|
335
363
|
|
336
364
|
model._name.on('changed') { puts 'name changed' }
|
@@ -344,7 +372,7 @@ Models trigger events when their data is updated. Currently models emit three e
|
|
344
372
|
model._items.on('removed') { puts 'item removed' }
|
345
373
|
model._items.delete_at(0)
|
346
374
|
# => item removed
|
347
|
-
|
375
|
+
```
|
348
376
|
|
349
377
|
## Automatic Model Conversion
|
350
378
|
|
@@ -352,6 +380,7 @@ Models trigger events when their data is updated. Currently models emit three e
|
|
352
380
|
|
353
381
|
For convience, when placing a hash inside of another model, it is automatically converted into a model. Models are similar to hashes, but provide support for things like persistance and triggering reactive events.
|
354
382
|
|
383
|
+
```ruby
|
355
384
|
user = Model.new
|
356
385
|
user._name = 'Ryan'
|
357
386
|
user._profiles = {
|
@@ -365,7 +394,7 @@ For convience, when placing a hash inside of another model, it is automatically
|
|
365
394
|
# => "http://www.twitter.com/ryanstout"
|
366
395
|
user._profiles.class
|
367
396
|
# => Model
|
368
|
-
|
397
|
+
```
|
369
398
|
|
370
399
|
Models are accessed differently from hashes. Instead of using model[:symbol] to access, you call a method model.method_name. This provides a dynamic unified store where setters and getters can be added without changing any access code.
|
371
400
|
|
@@ -373,6 +402,7 @@ Models are accessed differently from hashes. Instead of using model[:symbol] to
|
|
373
402
|
|
374
403
|
Arrays inside of models are automatically converted to an instance of ArrayModel. ArrayModels behave the same as a normal Array except that they can handle things like being bound to backend data and triggering reactive events.
|
375
404
|
|
405
|
+
```ruby
|
376
406
|
model = Model.new
|
377
407
|
model._items << {_name: 'item 1'}
|
378
408
|
model._items.class
|
@@ -381,11 +411,12 @@ Arrays inside of models are automatically converted to an instance of ArrayModel
|
|
381
411
|
model._items[0].class
|
382
412
|
# => Model
|
383
413
|
model._items[0]
|
384
|
-
|
414
|
+
```
|
385
415
|
|
386
416
|
|
387
417
|
To convert a Model or an ArrayModel back to a normal hash, call .to_h or .to_a respectively. To convert them to a JavaScript Object (for passing to some JavaScript code), call .to_n (to native).
|
388
418
|
|
419
|
+
```ruby
|
389
420
|
user = Model.new
|
390
421
|
user._name = 'Ryan'
|
391
422
|
user._profiles = {
|
@@ -398,26 +429,47 @@ To convert a Model or an ArrayModel back to a normal hash, call .to_h or .to_a r
|
|
398
429
|
|
399
430
|
items = ArrayModel.new([1,2,3,4])
|
400
431
|
items
|
432
|
+
```
|
401
433
|
|
402
434
|
# Controllers
|
403
435
|
|
404
|
-
A controller can be any class in Volt, however it is common to have that class inherit from ModelController. A model controller lets you specify a model that the controller works off of. This is a common pattern in Volt. To assign the current model, simply
|
436
|
+
A controller can be any class in Volt, however it is common to have that class inherit from ModelController. A model controller lets you specify a model that the controller works off of. This is a common pattern in Volt. To assign the current model for a controller, simply call the model method passing in one of the following:
|
405
437
|
|
438
|
+
1. A symbol representing the name of a provided collection model:
|
439
|
+
|
440
|
+
```ruby
|
441
|
+
class TodosController < ModelController
|
442
|
+
model :page
|
443
|
+
|
444
|
+
# ...
|
445
|
+
end
|
446
|
+
```
|
447
|
+
|
448
|
+
This can also be done at anytime on the controller instance:
|
449
|
+
|
450
|
+
```ruby
|
406
451
|
class TodosController < ModelController
|
407
452
|
def initialize
|
408
|
-
|
453
|
+
model :page
|
409
454
|
end
|
410
455
|
end
|
456
|
+
```
|
457
|
+
|
458
|
+
See the [provided collections](#provided-collections) section for a list of the available collection models.
|
459
|
+
|
460
|
+
You can also provide your own object to model.
|
411
461
|
|
412
|
-
Now any methods not defined on the TodosController will fall through to the
|
462
|
+
Now any methods not defined on the TodosController will fall through to the provided model. All views in views/{controller_name} will have this controller as the target for any ruby run in their bindings. This means that calls on self (implicit or with self.) will have the model as their target (after calling through the controller). This lets you add methods to the controller to control how the model is handled.
|
413
463
|
|
414
464
|
Controllers in the app/home component do not need to be namespaced, all other components should namespace controllers like so:
|
415
465
|
|
466
|
+
```ruby
|
416
467
|
module Auth
|
417
468
|
class LoginController < ModelController
|
418
469
|
# ...
|
419
470
|
end
|
420
471
|
end
|
472
|
+
```
|
421
473
|
|
422
474
|
Here "auth" would be the component name.
|
423
475
|
|
@@ -428,7 +480,7 @@ Apps are made up of Components. Each folder under app/ is a component. When yo
|
|
428
480
|
You can also use controls (see below) from one component in another. To do this, you must require the component from the component you wish to use them. This can be done in the ```config/dependencies.rb``` file. Just put
|
429
481
|
|
430
482
|
```ruby
|
431
|
-
component 'component_name'
|
483
|
+
component 'component_name'
|
432
484
|
```
|
433
485
|
|
434
486
|
in the file.
|
@@ -437,8 +489,10 @@ Dependencies act just like require in ruby, but for whole components.
|
|
437
489
|
|
438
490
|
Sometimes you may need to include an externally hosted JS file from a component. To do this, simply do the following in the dependencies.rb file:
|
439
491
|
|
492
|
+
```ruby
|
440
493
|
javascript_file 'http://code.jquery.com/jquery-2.0.3.min.js'
|
441
494
|
css_file '//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css'
|
495
|
+
```
|
442
496
|
|
443
497
|
Note above though that jquery and bootstrap are currently included by default. Using javascript_file and css_file will be mixed in with your component assets at the correct locations according to the order they occur in the dependencies.rb files.
|
444
498
|
|
@@ -456,7 +510,9 @@ Components can easily be shared as a gem. Volt provides a scaffold for componen
|
|
456
510
|
|
457
511
|
While developing, you can use the component by placing the following in your Gemfile:
|
458
512
|
|
459
|
-
|
513
|
+
```ruby
|
514
|
+
gem 'volt-{component_name}', path: '/path/to/folder/with/component'
|
515
|
+
```
|
460
516
|
|
461
517
|
Once the gem is ready, you can release it to ruby gems with:
|
462
518
|
|
@@ -537,7 +593,9 @@ This means that routes in volt have to go both from url to params and params to
|
|
537
593
|
|
538
594
|
Routes are specified on a per-component basis in the config/routes.rb file. Routes simply map from url to params.
|
539
595
|
|
596
|
+
```ruby
|
540
597
|
get "/todos", _controller: 'todos'
|
598
|
+
```
|
541
599
|
|
542
600
|
Routes take two arguments, a path, and a params hash. When a new url is loaded and the path is matched on a route, the params will be set to the params provided for that route.
|
543
601
|
|
@@ -547,7 +605,9 @@ When the params are changed, the url will be set to the path for the route that'
|
|
547
605
|
|
548
606
|
Route path's can also contain variables similar to bindings.
|
549
607
|
|
608
|
+
```ruby
|
550
609
|
get "/todos/{_index}", _controller: 'todos'
|
610
|
+
```
|
551
611
|
|
552
612
|
In the case above, if any url matches /todos/*, (where * is anything but a slash), it will be the active route. params._controller would be set to 'todos', and params._index would be set to the value in the path.
|
553
613
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.15
|
@@ -1,14 +1,10 @@
|
|
1
|
-
class ModelController
|
2
|
-
def initialize
|
3
|
-
self.model = @@default_model
|
4
|
-
end
|
5
|
-
|
1
|
+
class ModelController
|
6
2
|
def self.model(val)
|
7
3
|
@@default_model = val
|
8
4
|
end
|
9
5
|
|
10
6
|
# Sets the current model on this controller
|
11
|
-
def model
|
7
|
+
def model(val)
|
12
8
|
if val.is_a?(Symbol) || val.is_a?(String)
|
13
9
|
collections = [:page, :store, :params]
|
14
10
|
if collections.include?(val.to_sym)
|
@@ -16,9 +12,22 @@ class ModelController
|
|
16
12
|
else
|
17
13
|
raise "#{val} is not the name of a valid model, choose from: #{collections.join(', ')}"
|
18
14
|
end
|
19
|
-
|
15
|
+
elsif model
|
20
16
|
@model = model
|
17
|
+
else
|
18
|
+
raise "model can not be #{model.inspect}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.new(*args, &block)
|
23
|
+
inst = self.allocate
|
24
|
+
if @@default_model
|
25
|
+
inst.model(@@default_model || :page)
|
21
26
|
end
|
27
|
+
|
28
|
+
inst.initialize(*args, &block)
|
29
|
+
|
30
|
+
return inst
|
22
31
|
end
|
23
32
|
|
24
33
|
def page
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: volt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Stout
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|