Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 0002c05

Browse files
committed
fixup 1
- Fix typos. - Improve wording. - Simplify links. - Add warnings: - Firewalls blocking `git:`. - File include order (i.e. `.module` files before other files). - Improve tests: - Remove unnecessary locals when calling `$componentController()`. - Extract protractor queries.
1 parent d68265f commit 0002c05

12 files changed

+94
-79
lines changed

docs/content/tutorial/index.ngdoc

+14-1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,19 @@ cd angular-phonecat
9696
The tutorial instructions, from now on, assume you are running all commands from within the
9797
`angular-phonecat` directory.
9898

99+
<div class="alert alert-warning">
100+
<p>
101+
`git` and other tools (for example `bower` - see below), often use the `git:` protocol for
102+
accessing files in remote repositories. Some firewall configurations are blocking `git://` URLs,
103+
which leads to errors when trying to clone repositories or download dependencies. (For example
104+
corporate firewalls are "notorious" for blocking `git:`.)
105+
</p>
106+
<p>
107+
If you run into this issue, you can force the use of `https:` instead, by running the following
108+
command: `git config --global url."https://".insteadOf git://`
109+
</p>
110+
</div>
111+
99112

100113
### Install Node.js
101114

@@ -257,7 +270,7 @@ npm run update-webdriver
257270
the [Java Development Kit (JDK)][jdk] to be installed on your local machine. Check this
258271
by running `java -version` from the command line.
259272

260-
If JDK is not already install, you can download it [here][jdk-download].
273+
If JDK is not already installed, you can download it [here][jdk-download].
261274
</div>
262275

263276
Since Protractor works by interacting with a running application, we need to start our web server:

docs/content/tutorial/step_00.ngdoc

+4-4
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ directive is used to flag the HTML element that Angular should consider to be th
7979
our application. This gives application developers the freedom to tell Angular if the entire HTML
8080
page or only a portion of it should be treated as the AngularJS application.
8181

82-
For more info on `ngApp`, check out the {@link ng.directive:ngApp API Reference}.
82+
For more info on `ngApp`, check out the {@link ngApp API Reference}.
8383

8484
<br />
8585
**`angular.js` script tag:**
@@ -90,9 +90,9 @@ For more info on `ngApp`, check out the {@link ng.directive:ngApp API Reference}
9090

9191
This code downloads the `angular.js` script which registers a callback that will be executed by the
9292
browser when the containing HTML page is fully downloaded. When the callback is executed, Angular
93-
looks for the {@link ng.directive:ngApp ngApp} directive. If Angular finds the directive, it will
94-
bootstrap the application with the root of the application DOM being the element on which the
95-
`ngApp` directive was defined.
93+
looks for the {@link ngApp ngApp} directive. If Angular finds the directive, it will bootstrap the
94+
application with the root of the application DOM being the element on which the `ngApp` directive
95+
was defined.
9696

9797
For more info on bootstrapping your app, checkout the [Bootstrap](guide/bootstrap) section of the
9898
Developer Guide.

docs/content/tutorial/step_02.ngdoc

+6-7
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,17 @@ The view is constructed by Angular from this template.
5050
</html>
5151
```
5252

53-
We replaced the hard-coded phone list with the {@link ng.directive:ngRepeat ngRepeat} directive and
54-
two {@link guide/expression Angular expressions}:
53+
We replaced the hard-coded phone list with the {@link ngRepeat ngRepeat} directive and two
54+
{@link guide/expression Angular expressions}:
5555

5656
* The `ng-repeat="phone in phones"` attribute on the `<li>` tag is an Angular repeater directive.
5757
The repeater tells Angular to create a `<li>` element for each phone in the list, using the `<li>`
5858
tag as the template.
5959
* The expressions wrapped in curly braces (`{{phone.name}}` and `{{phone.snippet}}`) will be
6060
replaced by the values of the expressions.
6161

62-
We have also added a new directive, called {@link ng.directive:ngController ngController}, which
63-
attaches a `PhoneListController` **controller** to the `<body>` tag. At this point:
62+
We have also added a new directive, called {@link ngController ngController}, which attaches a
63+
`PhoneListController` **controller** to the `<body>` tag. At this point:
6464

6565
* `PhoneListController` is in charge of the DOM sub-tree under (and including) the `<body>` element.
6666
* The expressions in curly braces (`{{phone.name}}` and `{{phone.snippet}}`) denote bindings, which
@@ -112,9 +112,8 @@ Although the controller is not yet doing very much, it plays a crucial role. By
112112
for our data model, the controller allows us to establish data-binding between the model and the
113113
view. We connected the dots between the presentation, data, and logic components as follows:
114114

115-
* The {@link ng.directive:ngController ngController} directive, located on the `<body>` tag,
116-
references the name of our controller, `PhoneListController` (located in the JavaScript file
117-
`app.js`).
115+
* The {@link ngController ngController} directive, located on the `<body>` tag, references the name
116+
of our controller, `PhoneListController` (located in the JavaScript file `app.js`).
118117

119118
* The `PhoneListController` controller attaches the phone data to the `$scope` that was injected
120119
into our controller function. This _scope_ is a prototypal descendant of the _root scope_ that was

docs/content/tutorial/step_03.ngdoc

+5-5
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,9 @@ application or vice versa.
6464
</p>
6565
</div>
6666

67-
To create a component, we use the `.component()` method of an {@link module Angular module}. We must
68-
provide the name of the component and the Component Definition Object (CDO for short).
67+
To create a component, we use the {@link angular.Module#component .component()} method of an
68+
{@link module Angular module}. We must provide the name of the component and the Component
69+
Definition Object (CDO for short).
6970

7071
Remember that (since components are also directives) the name of the component is in `camelCase`,
7172
but we will use `kebab-case`, when referring to it in our HTML.
@@ -100,8 +101,7 @@ inside the controller constructor), instead of directly to the scope.
100101

101102
From the template, we can refer to our controller instance using an alias. This way, the context of
102103
evaluation for our expressions is even more clear. By default, components use `$ctrl` as the
103-
controller alias, but we can override it, should the need arise. (It is a very uncommon need though,
104-
so we will be sticking with `$ctrl` most of the time.)
104+
controller alias, but we can override it, should the need arise.
105105

106106
There are more options available, so make sure you check out the
107107
{@link ng.$compileProvider#component API Reference}, before using `.component()` in your own
@@ -223,7 +223,7 @@ describe('phoneList', function() {
223223
describe('PhoneListController', function() {
224224

225225
it('should create a `phones` model with 3 phones', inject(function($componentController) {
226-
var ctrl = $componentController('phoneList', {$scope: {}});
226+
var ctrl = $componentController('phoneList');
227227

228228
expect(ctrl.phones.length).toBe(3);
229229
}));

docs/content/tutorial/step_04.ngdoc

+16-11
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ We will keep this in mind though, as we add more features.
5353

5454
So, now that we learned we should put everything in its own file, our `app/` directory will soon be
5555
full with dozens of files and specs (remember we keep our unit test files next to the corresponding
56-
source code files). What's more important, logically related files will not be groupped together; it
56+
source code files). What's more important, logically related files will not be grouped together; it
5757
will be really difficult of locate all files related to a specific section of the application and
5858
make a change or fix a bug.
5959

@@ -66,8 +66,8 @@ parts of the application. We will put those inside `app/core/`.
6666

6767
<div class="alert alert-info">
6868
<p>
69-
Other typical names for our `core` directory are `common` and `components`. The latter is kind
70-
of misleading though, as it will contain other things than components as well.
69+
Other typical names for our `core` directory are `shared`, `common` and `components`. The last
70+
one is kind of misleading though, as it will contain other things than components as well.
7171
</p>
7272
<p>
7373
(This is mostly a relic of the past, when "components" just meant the generic building blocks of
@@ -90,7 +90,7 @@ Based on what we have discussed so far, here is our directory/file layout for th
9090
## Using Modules
9191

9292
As previously mentioned, one of the benefits of having a modular architecture is code reuse &mdash;
93-
not only inside the same application, but across application too. There is one final step in making
93+
not only inside the same application, but across applications too. There is one final step in making
9494
this code reuse frictionless:
9595

9696
* Each feature/section should declare its own module and all related entities should register
@@ -175,11 +175,16 @@ will make all entities registered on `phoneList` available on `phonecatApp` as w
175175
we have created. This might seem tedious, but is totally worth it.
176176
</p>
177177
<p>
178-
In a production-ready application, you are better off concatenating and minifying all your
179-
JavaScript files anyway (for performance reasons), so this won't be an issue any more.
178+
In a production-ready application, you would concatenate and minify all your JavaScript files
179+
anyway (for performance reasons), so this won't be an issue any more.
180180
</p>
181181
</div>
182182

183+
<div class="alert alert-warning">
184+
Note that files defining a module (i.e. `.module.js`) need to be included before other files that
185+
add features (e.g. components, controllers, services, filters) to that module.
186+
</div>
187+
183188

184189
## External Templates
185190

@@ -193,7 +198,7 @@ IDE/editor has to offer (e.g. HTML-specific color-highlighting and auto-completi
193198
our component definitions cleaner.
194199

195200
So, while it's perfectly fine to keep our component templates inline (using the `template` property
196-
of the CDO), we decided to use an external template for our `phoneList` component. In order to
201+
of the CDO), we are going to use an external template for our `phoneList` component. In order to
197202
denote that we are using an external template, we use the `templateUrl` property and specify the URL
198203
that our template will be loaded from. Since we want to keep our template close to where the
199204
component is defined, we place it inside `app/phone-list/`.
@@ -242,7 +247,7 @@ HTTP request to get the template from `app/phone-list/phone-list.template.html`.
242247

243248
## Final Directory/File Layout
244249

245-
After all the refactorings that took place, this is how our application looks like from the outside:
250+
After all the refactorings that took place, this is how our application looks from the outside:
246251

247252
<br />
248253
**`/`:**
@@ -289,10 +294,10 @@ If not already done so, run the tests (using the `npm test` command) and verify
289294
pass.
290295

291296
<div class="alert alert-success">
292-
One of the great things about tests is the confidence the provide, when refactoring your
297+
One of the great things about tests is the confidence they provide, when refactoring your
293298
application. It's easy to break something as you start moving files around and re-arranging
294-
modules. Having a good test coverage is the quickest, easiest and most reliable way of knowing
295-
that your application will continue to work as expected.
299+
modules. Having good test coverage is the quickest, easiest and most reliable way of knowing that
300+
your application will continue to work as expected.
296301
</div>
297302

298303

docs/content/tutorial/step_05.ngdoc

+11-11
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,12 @@ We made no changes to the component's controller.
5252
</div>
5353
```
5454

55-
We added a standard HTML `<input>` tag and used Angular's
56-
{@link ng.filter:filter filter} function to process the input for the
57-
{@link ng.directive:ngRepeat ngRepeat} directive.
55+
We added a standard HTML `<input>` tag and used Angular's {@link ng.filter:filter filter} function
56+
to process the input for the {@link ngRepeat ngRepeat} directive.
5857

59-
By virtue of the {@link ng.directive:ngModel ngModel} directive, this lets a user enter search
60-
criteria and immediately see the effects of their search on the phone list. This new code
61-
demonstrates the following:
58+
By virtue of the {@link ngModel ngModel} directive, this lets a user enter search criteria and
59+
immediately see the effects of their search on the phone list. This new code demonstrates the
60+
following:
6261

6362
* Data-binding: This is one of the core features in Angular. When the page loads, Angular binds the
6463
value of the input box to the data model variable specified with `ngModel` and keeps the two in
@@ -83,8 +82,8 @@ demonstrates the following:
8382

8483
In previous steps, we learned how to write and run unit tests. Unit tests are perfect for testing
8584
controllers and other parts of our application written in JavaScript, but they can't easily
86-
test DOM manipulation or the wiring of our application. For these, an end-to-end (E2E) test is a
87-
much better choice.
85+
test templates, DOM manipulation or interoperability of components and services. For these, an
86+
end-to-end (E2E) test is a much better choice.
8887

8988
The search feature was fully implemented via templates and data-binding, so we'll write our first
9089
E2E test, to verify that the feature works.
@@ -132,13 +131,14 @@ Jasmine, the E2E test uses APIs of [Protractor][protractor]. Read about the Prot
132131
[Protractor API Docs][protractor-docs].
133132

134133
Much like Karma is the test runner for unit tests, we use Protractor to run E2E tests. Try it with
135-
`npm run protractor`. E2E tests are slow, so unlike with unit tests, Protractor will exit after the
134+
`npm run protractor`. E2E tests take time, so unlike with unit tests, Protractor will exit after the
136135
tests run and will not automatically rerun the test suite on every file change.
137136
To rerun the test suite, execute `npm run protractor` again.
138137

139138
<div class="alert alert-info">
140-
**Note:** You must ensure your application is being served via a web server to test with
141-
protractor. You can do this by using `npm start`.
139+
**Note:** In order for protractor to access and run tests against your application, it must be
140+
served via a web server. In a different terminal/command line window, run `npm start` to fire up
141+
the web server.
142142
</div>
143143

144144

docs/content/tutorial/step_06.ngdoc

+9-7
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ We made the following changes to the `phone-list.template.html` template:
6464

6565
<img class="diagram" src="img/tutorial/tutorial_06.png">
6666

67-
* We then chained the `filter` filter with the {@link ng.filter:orderBy orderBy} filter to further
68-
process the input for the repeater. `orderBy` is a filter that takes an input array, copies it and
69-
reorders the copy which is then returned.
67+
* We then chained the `filter` filter with the {@link orderBy orderBy} filter to further process the
68+
input for the repeater. `orderBy` is a filter that takes an input array, copies it and reorders
69+
the copy which is then returned.
7070

7171
Angular creates a two way data-binding between the select element and the `$ctrl.orderProp` model.
7272
`$ctrl.orderProp` is then used as the input for the `orderBy` filter.
@@ -143,7 +143,7 @@ describe('phoneList', function() {
143143
var ctrl;
144144

145145
beforeEach(inject(function($componentController) {
146-
ctrl = $componentController('phoneList', {$scope: {}});
146+
ctrl = $componentController('phoneList');
147147
}));
148148

149149
it('should create a `phones` model with 3 phones', function() {
@@ -183,23 +183,25 @@ Let's turn our attention to the E2E tests.
183183
...
184184

185185
it('should be possible to control phone order via the drop-down menu', function() {
186+
var queryField = element(by.model('$ctrl.query'));
187+
var orderSelect = element(by.model('$ctrl.orderProp'));
188+
var nameOption = orderSelect.element(by.css('option[value="name"]'));
186189
var phoneNameColumn = element.all(by.repeater('phone in $ctrl.phones').column('phone.name'));
187-
var query = element(by.model('$ctrl.query'));
188190

189191
function getNames() {
190192
return phoneNameColumn.map(function(elem) {
191193
return elem.getText();
192194
});
193195
}
194196

195-
query.sendKeys('tablet'); // Let's narrow the dataset to make the test assertions shorter
197+
queryField.sendKeys('tablet'); // Let's narrow the dataset to make the assertions shorter
196198

197199
expect(getNames()).toEqual([
198200
'Motorola XOOM\u2122 with Wi-Fi',
199201
'MOTOROLA XOOM\u2122'
200202
]);
201203

202-
element(by.model('$ctrl.orderProp')).element(by.css('option[value="name"]')).click();
204+
nameOption.click();
203205

204206
expect(getNames()).toEqual([
205207
'MOTOROLA XOOM\u2122',

docs/content/tutorial/step_07.ngdoc

+11-10
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ in this tutorial.)
7777

7878
The `$http` service returns a {@link ng.$q promise object}, which has a `then()` method. We call
7979
this method to handle the asynchronous response and assign the phone data to the controller, as a
80-
model called `phones`. Notice that Angular detected the JSON response and parsed it for us into the
81-
`data` property of the `response` object passed to our callback!
80+
property called `phones`. Notice that Angular detected the JSON response and parsed it for us into
81+
the `data` property of the `response` object passed to our callback!
8282

83-
Since we are making the assignment of the `phones` model in a callback function, where the `this`
83+
Since we are making the assignment of the `phones` property in a callback function, where the `this`
8484
value is not defined, we also introduce a local variable called `self` that points back to the
8585
controller instance.
8686

@@ -207,7 +207,7 @@ describe('phoneList', function() {
207207
$httpBackend.expectGET('phones/phones.json')
208208
.respond([{name: 'Nexus S'}, {name: 'Motorola DROID'}]);
209209

210-
ctrl = $componentController('phoneList', {$scope: {}});
210+
ctrl = $componentController('phoneList');
211211
}));
212212

213213
...
@@ -242,17 +242,18 @@ request from the controller. To do this we:
242242
{@link ngMock.$httpBackend mock version} of the service that in a production environment
243243
facilitates all XHR and JSONP requests. The mock version of this service allows us to write tests
244244
without having to deal with native APIs and the global state associated with them — both of which
245-
make testing a nightmare.
245+
make testing a nightmare. It also overcomes the asynchronous nature of these calls, which would
246+
slow down unit tests.
246247

247248
* Use the `$httpBackend.expectGET()` method to train the `$httpBackend` service to expect an
248249
incoming HTTP request and tell it what to respond with. Note that the responses are not returned
249250
until we call the `$httpBackend.flush()` method.
250251

251-
Now we will make assertions to verify that the `phones` model doesn't exist on the controller before
252-
the response is received:
252+
Now we will make assertions to verify that the `phones` property doesn't exist on the controller
253+
before the response is received:
253254

254255
```js
255-
it('should create a `phones` model with 2 phones fetched with `$http`', function() {
256+
it('should create a `phones` property with 2 phones fetched with `$http`', function() {
256257
expect(ctrl.phones).toBeUndefined();
257258

258259
$httpBackend.flush();
@@ -265,12 +266,12 @@ the response is received:
265266
{@link ngMock.$httpBackend#flushing-http-requests Flushing HTTP requests} in the mock
266267
`$httpBackend` documentation for a full explanation of why this is necessary.
267268

268-
* We make the assertions, verifying that the `phones` model now exists on the controller.
269+
* We make the assertions, verifying that the `phones` property now exists on the controller.
269270

270271
Finally, we verify that the default value of `orderProp` is set correctly:
271272

272273
```js
273-
it('should set a default value for the `orderProp` model', function() {
274+
it('should set a default value for the `orderProp` property', function() {
274275
expect(ctrl.orderProp).toBe('age');
275276
});
276277
```

0 commit comments

Comments
 (0)