ninjs 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/README.textile +138 -8
  2. metadata +2 -9
data/README.textile CHANGED
@@ -2,7 +2,7 @@ h1. Readme
2
2
 
3
3
  h2. About
4
4
 
5
- Ninjs (No Inheritance Necessary) is a command line application written in ruby that leverages the "Sprockets":http://getsprockets.org JavaScript compiler to create modular javascript applications without having to compile your scripts manually. Ninjs also contains a very barebones JavaScript framework to enforce best practices like name-spacing and modular separation.
5
+ Ninjs (No Inheritance Necessary) is a command line application written in ruby that leverages the "Sprockets":http://getsprockets.org JavaScript compiler to create modular javascript applications without having to compile your scripts manually. Ninjs also contains a "'Good Parts'":http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=sr_1_1?ie=UTF8&qid=1294628522&sr=8-1 JavaScript framework to encourage best practices like name-spacing and modular separation.
6
6
 
7
7
  h2. Installation
8
8
 
@@ -22,20 +22,150 @@ This will create a Ninjs application in the current working directory. Now we ca
22
22
 
23
23
  h1. Create a Ninjs module
24
24
 
25
- Create a module file in the /modules directory. By convention, we'll name the file with a suffix of .module. An example of a module named login would look like this:
25
+ Create a module file in the /modules directory. By convention, we'll name the file with a suffix of .module. An example of a module named hello would look like this:
26
26
 
27
- /modules/login.module.js
27
+ /modules/hello.module.js
28
28
 
29
- The basic functionality of a module is to encapsulate code into logical container. Think of a module as a class in the sense that it allows to name-space properties and methods. A Ninjs module is an extremely lightweight object that contains a very simple api which helps you write clear, concise code. The following is the bare minimum you need to have a working module a.k.a Ninjs' "Hello World":
29
+ The basic functionality of a module is to encapsulate specific logic into a container. Think of a module as a class in the sense that it allows to name-space properties and methods. A Ninjs module is an extremely lightweight object that contains a very simple api which helps you write clear, concise code. The following is the bare minimum you need to have a working module a.k.a Ninjs' "Hello World":
30
30
 
31
31
  <pre name="code" class="brush: js;">
32
- MyApplication.add_module('login');
32
+ MyApplication.add_module('hello');
33
33
 
34
- MyApplication.login.actions = function() {
34
+ MyApplication.hello.actions = function() {
35
+ this.say_hello();
36
+ };
37
+
38
+ MyApplication.hello.say_hello = function() {
39
+ alert('Hello World');
40
+ };
41
+
42
+ MyApplication.hello.run();
43
+ </pre>
44
+
45
+ The run method will execute the actions method. Please note that the "run" method will wait for the DOM to be ready before it is executed. If you wish the actions to be executed immediately, you may call the execute method like so:
46
+
47
+ <pre name="code" class="brush: js;">
48
+ MyApplication.hello.execute();
49
+ </pre>
50
+
51
+ This pattern allows you to write in a literate style while making your intentions clear and methods succinct. However, if you prefer a shorter syntax or make your module completely protable (transplant to any application), Ninjs defines two aliases to work with your application and modules that are more terse. Your application object will be aliased as "_" (underscore). When using either the run or execute methods to call the module's actions, the module will be available through the "__" alias. The previous hello module would look like the following:
52
+
53
+ <pre name="code" class="brush: js;">
54
+ _.add_module('hello');
55
+
56
+ _.hello.actions = function() {
57
+ __.say_hello();
58
+ };
59
+
60
+ _.hello.say_hello = function() {
35
61
  alert('Hello World');
36
62
  };
37
63
 
38
- MyApplication.login.run();
64
+ _.hello.run();
65
+ </pre>
66
+
67
+ This not only makes the module less cumbersome to write, it also allows you to copy the code directly to another Ninjs application and run it without any renaming. Remember one underscore is a reference to the application and two underscores is a reference to the current module.
68
+
69
+ You may ask why we are calling say_hello() in the actions method instead of just alerting the string in actions itself. Let's set aside the fact that this is a trivial example and assume we will be adding many more methods to the module. If we simply added all of our module code inside actions, we'd quickly have a soup of code in there which would be difficult to follow. I prefer my actions method to be a list of methods called in the order they are defined. This let's my module tell a consistent story from top to bottom. The actions method serves as a table of contents. Consider a slightly more sophisticated hello module:
70
+
71
+ <pre name="code" class="brush: js;">
72
+ MyApplication.add_module('hello');
73
+
74
+ MyApplication.hello.actions = function() {
75
+ this.define_properties();
76
+ this.say_hello();
77
+ };
78
+
79
+ MyApplication.hello.define_properties() = function() {
80
+ this.greeting = 'Hello';
81
+ this.name = 'World';
82
+ }
83
+
84
+ MyApplication.hello.say_hello = function() {
85
+ var message = this.greeting_string();
86
+ alert(message);
87
+ };
88
+
89
+ MyApplication.hello.greeting_string = function() {
90
+ return this.greeting + ' ' + this.name + '!';
91
+ };
92
+
93
+ MyApplication.hello.run();
39
94
  </pre>
40
95
 
41
- In the real world however, you're probably waiting for the DOM to load before you want your
96
+ We can see what this module does by simply glancing at the actions method. From there, if methods are kept short and follow the "single responsibiliy principle":http://en.wikipedia.org/wiki/Single_responsibility_principle, it will be easy to follow and test.
97
+
98
+ h2. Create module elements
99
+
100
+ Another common best practice that Ninjs encourages is cacheing your element selectors. For example, when using jQuery to select a DOM element, it's best practice to assign the result of the selection to a variable incase you need it again. Here's what it looks like in practice:
101
+
102
+ <pre name="code" class="brush: js;">
103
+ // Bad no-caching
104
+ $('#some-element').css({ 'background-color': '#FF0000' });
105
+ $('#some-element').html("I turned red");
106
+
107
+ // Good caching
108
+ var some_element = $('#some-element);
109
+ some_element.css({ 'background-color': '#FF0000' });
110
+ some_element.html("I turned red");
111
+ </pre>
112
+
113
+ When we cache our selections, we only have to search the DOM once, improving performance.
114
+
115
+ The only problem with this is that we tend to manipulate a lot of selections and our code can become littered with them. At worst, they're strewn about the file where ever they are first used, making it easy to "re-cache" them. At best all our selections are cached in one pace and easy to see to prevent us from accidentally caching them twice. Ninjs goes a step further by separating these cached selectors to their own file in the elements folder.
116
+
117
+ Elements belong to a module and can be added using the elements method. To add elements to the hello module, let's add a hello.elements.js file in the elements folder. Next add the elements to the module with the elements method:
118
+
119
+ <pre name="code" class="brush: js;">
120
+ MyApplication.hello.elements(function() {
121
+ this.message_box = $('#message-box');
122
+ });
123
+ </pre>
124
+
125
+ And that's it for the elements code. We've added a cached element with the id of "message-box" to our module. All there is left is to add the elements to the module using the "Sprockets require directive":http://getsprockets.org/installation_and_usage#specifying_dependencies_with_the_require_directive
126
+
127
+ <pre name="code" class="brush: js;">
128
+ MyApplication.add_module('hello');
129
+
130
+ //= require '../elements/hello.elements.js'
131
+
132
+ MyApplication.hello.actions = function() {
133
+ this.define_properties();
134
+ this.say_hello();
135
+ };
136
+
137
+ MyApplication.hello.define_properties() = function() {
138
+ this.greeting = 'Hello';
139
+ this.name = 'World';
140
+ }
141
+
142
+ MyApplication.hello.say_hello = function() {
143
+ var message = this.greeting_string();
144
+ alert(message);
145
+ };
146
+
147
+ MyApplication.hello.greeting_string = function() {
148
+ return this.greeting + ' ' + this.name + '!';
149
+ };
150
+
151
+ MyApplication.hello.run();
152
+ </pre>
153
+
154
+ Be sure to require the elements file after the "add_module" method is called. Now all elements defined in the elements method will be available to the module. Let's take our hello example and instead of alerting the greeting, let's put it in the message_box element (assuming an html page with this element):
155
+
156
+ <pre name="code" class="brush: js;">
157
+ ...
158
+
159
+ MyApplication.hello.say_hello = function() {
160
+ var message = this.greeting_string();
161
+ this.message_box.html(message);
162
+ };
163
+
164
+ ...
165
+ </pre>
166
+
167
+ Again, this pattern keeps the logic very clear and our code very concise. It's easy to read, test, and refactor. Be careful when naming your cached elements, be sure you're not overwriting another property. With time you'll develop your own naming conventions and standards. The important thing is to focus on good semantic names that accurately describe the properties and behavior of your application.
168
+
169
+ Most modules will be exactly like the one we just created, with more methods. However, there is one more piece that helps you achieve greater modularity, which is Ninjs models.
170
+
171
+ h2. Create a Ninjs model
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ninjs
3
3
  version: !ruby/object:Gem::Version
4
- hash: 59
5
4
  prerelease: false
6
5
  segments:
7
6
  - 0
8
7
  - 9
9
- - 0
10
- version: 0.9.0
8
+ - 1
9
+ version: 0.9.1
11
10
  platform: ruby
12
11
  authors:
13
12
  - Dayton Nolan
@@ -26,7 +25,6 @@ dependencies:
26
25
  requirements:
27
26
  - - ">="
28
27
  - !ruby/object:Gem::Version
29
- hash: 3
30
28
  segments:
31
29
  - 0
32
30
  version: "0"
@@ -40,7 +38,6 @@ dependencies:
40
38
  requirements:
41
39
  - - ">="
42
40
  - !ruby/object:Gem::Version
43
- hash: 3
44
41
  segments:
45
42
  - 0
46
43
  version: "0"
@@ -54,7 +51,6 @@ dependencies:
54
51
  requirements:
55
52
  - - ">="
56
53
  - !ruby/object:Gem::Version
57
- hash: 3
58
54
  segments:
59
55
  - 0
60
56
  version: "0"
@@ -68,7 +64,6 @@ dependencies:
68
64
  requirements:
69
65
  - - ">="
70
66
  - !ruby/object:Gem::Version
71
- hash: 3
72
67
  segments:
73
68
  - 0
74
69
  version: "0"
@@ -100,7 +95,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
95
  requirements:
101
96
  - - ">="
102
97
  - !ruby/object:Gem::Version
103
- hash: 3
104
98
  segments:
105
99
  - 0
106
100
  version: "0"
@@ -109,7 +103,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
103
  requirements:
110
104
  - - ">="
111
105
  - !ruby/object:Gem::Version
112
- hash: 3
113
106
  segments:
114
107
  - 0
115
108
  version: "0"