Compare commits

...

120 Commits

Author SHA1 Message Date
Pete Bacon Darwin e242e9b595 fix(angular.merge): do not merge __proto__ property
By blocking `__proto__` on deep merging, this commit
prevents the `Object` prototype from being polluted.
2019-11-07 15:40:09 +00:00
Pete Bacon Darwin 33b5c5067e chore(docs): fix linting issue 2018-11-14 09:45:37 +00:00
Pete Bacon Darwin 7a88a34228 chore(package): update protractor & webdriver dependencies 2018-11-14 09:27:05 +00:00
Jason Bedard dc1c180783 fix(input): prevent browsers from autofilling hidden inputs
Autofilling with previous values (which will then be `$interpolate`ed) could lead to XSS or errors
2018-11-14 09:24:39 +00:00
Pete Bacon Darwin 6592693aad chore(docs-app): ensure ToC links contain the path
Without the path the link is always pointing to the
root page, rather than the current page, which means
that copying the link address or opening the page in
a new tab is broken.

Closes #16608
2018-06-22 21:56:50 +01:00
Pete Bacon Darwin dc3955ca63 style(validators): add an arbitrary jsdoc comment to fix closure compiler builds
Closure compiler complains that the factory function for these validator
directives do not have the parameter documented in the preceding jsdoc
comment. These comments are actually describing the directives and not
their factory functions and so have `@param` tags that do not match the
factory function signature.

This change adds a simple empty(ish) jsdoc comment between the
directive's jsdoc comment and the factory function, which silences
the error from the closure compiler. Luckily the ngdoc processing
does not require these jsdoc comments to be attached to any code
items, so that is not affected by this change.
2018-05-15 07:37:02 +01:00
Martin Staffa 9a3737932a chore(package.json): change distTag to "previous_1_6" 2018-05-09 19:43:32 +02:00
George Kalpakas 0ae0887b2f fix(input[date]): correctly parse 2-digit years
When parsing a date string value, AngularJS uses `new Date(year, ...)`
to create a Date object and assign it to the model. In the constructor,
2-digit years map to 1900-1999, so the created Date object has the wrong
value for year.
This commit fixes it, by explicitly using `setFullYear()` to set the
year to the correct value, when necessary.

Fixes #16537

Closes #16539
2018-04-27 18:54:28 +03:00
Martin Staffa 2549313eab docs(CHANGELOG.md): update date for 1.6.10 2018-04-17 18:35:33 +02:00
Martin Staffa 26fccb9943 docs(CHANGELOG.md): add changes for 1.6.10 2018-04-12 18:40:08 +02:00
Peter Bacon Darwin efb822c58d feat($rootScope): allow suspending and resuming watchers on scope
This can be very helpful for external modules that help making the digest
loop faster by ignoring some of the watchers under some circumstance.
Example: https://github.com/shahata/angular-viewport-watch

Thanks to @shahata for the original implementation.

Closes #5301
Closes #16308
2018-04-12 10:35:21 +02:00
Martin Staffa b7d1e0fbdb fix($compile): throw error in $onChanges immediately
This brings it in line with how we throw errors in a digest cycle,
and also avoids throwing an array.

Closes #15578
Closes #16492
2018-04-12 10:29:50 +02:00
Martin Staffa 31ea071f2e docs($compile): add known issues with replace:true
Closes #16523

Related #2573
Related #5695
Related #9837
Related #10612
2018-04-11 17:55:27 +02:00
Martin Staffa abe6acf598 test(input): fix date type tests with max + timezone
Closes #16526
2018-04-10 23:04:31 +02:00
George Kalpakas f04e04e0e6 fix($compile): correctly handle null/undefined href attrs.$set()
Accidentally broken while backporting #14890.

Since #14890, `$$sanitizeUri()` can no longer handle `null`/`undefined` values.
In 1.7.x, there are no such calls.
In 1.6.x, there is still one such calls inside `Attributes.$set()`, so it needs to be adjusted accordingly.

Closes #16520
2018-04-09 10:23:24 +02:00
Martin Staffa 4355dee21d fix(input): allow overriding timezone for date input types
This commit also fixes a bug where part of the Date object
was re-used even after the input was emptied.

Fixes #16181
Closes #13382
Closes #16336
2018-04-06 16:45:44 +02:00
Mohamed amr 2f0ac696cb fix(input): take timezone into account when validating minimum and maximum in date types
Closes #16342
Closes #16390
2018-04-06 16:45:26 +02:00
George Kalpakas da3d96c0ea refactor(urlResolve): return already parsed URLs unchanged
Closes #14890
2018-04-05 10:11:30 +03:00
Georgios Kalpakas bc775759c8 feat($http): support sending XSRF token to whitelisted origins
Normally, the XSRF token will not be set for cross-origin requests.
With this commit, it is possible to whitelist additional origins, so that requests to these origins
will include the XSRF token header.

Fixes #7862
2018-04-05 10:10:45 +03:00
Michał Gołębiowski-Owczarek fa4451d57f docs(jqLite): document that append doesn't work well with a multi-node object
Contrary to jQuery jqLite's append doesn't clone elements so will not work
correctly when invoked on a jqLite object containing more than one DOM node.

Refs #11446
Closes #16517
2018-04-04 09:47:32 +02:00
Michał Gołębiowski-Owczarek a0c55af985 fix(jqLite): use XHTML-compliant HTML as input for jqLite
Fixes #6917
Closes #16518
2018-04-04 09:47:16 +02:00
Michał Gołębiowski-Owczarek d1dd6a3624 chore(*): stop testing on Edge 15 due to its instability
Edge 15 disconnects from Karma frequently causing extreme build instability.
We are testing on Edge 16 & Edge 17 should be released soon anyway.

Closes #16516
2018-03-28 14:46:04 +02:00
Michał Gołębiowski-Owczarek e5eaecc32b tests(ngMock): remove a broken jqLite cache clearing (#16515)
This commit removes the resetting of `angular.element.cache` in some tests;
this was desynchronizing jqLite.cache & the local jqCache variable and since
some parts of the code use one of them and some the other one, it was breaking
JQLite._data. `angular.element.cache` doesn't even exist when jQuery 2+ is used.

Closes #16515
Refs #16512
2018-03-28 13:22:58 +02:00
Giuseppe Scoppino 24ddbafbdf docs(guide/Internet Explorer Compatibility): include warnings for usage of 'disabled' attribute
* docs(guide/Internet Explorer Compatibility): Mention 'disabled' attribute

Setting the 'disabled' attribute on an element that has descendant elements has unexpected behavior in Internet Explorer 11.

* Input elements that are descendants have the text content of the 'placeholder' attribute inserted as the value (and it is not removed when typing in the field).
* Select elements that are descendants are disabled.

To avoid this issue, it is important to not set `disabled` or `ng-disabled` on an element that has descendant form elements. Normally these should only be used on actual form controls so the issue would not manifest.

The issue can also appear if a directive/component is named 'disabled' or takes an attribute named 'disabled' as an input/output attribute, so avoid these.

Closes  #16490
Related #15700
2018-03-19 18:04:17 +01:00
Martin Staffa 980b69dcae feat(minErr): strip error url from error parameters
Related https://github.com/angular/angular.js/issues/14744
2018-03-19 18:04:11 +01:00
Martin Staffa 52e46683bf fix(minErr): update url to https 2018-03-19 18:04:08 +01:00
Martin Staffa 0b0a122888 chore(travis): update iOs test browsers
Closes #16493
2018-03-16 16:49:57 +01:00
Martin Staffa b166f2b34a docs(ngShow/ngHide): add note about flicker when toggling elements
Related to https://github.com/angular/angular.js/issues/14015

Closes #16489
2018-03-16 13:30:58 +02:00
George Kalpakas ac06fb6592 style($interval): fix indentation 2018-03-13 21:25:47 +02:00
George Kalpakas 20dbc1161f style($timeout): fix indentation 2018-03-13 21:25:22 +02:00
George Kalpakas f78268fbf7 docs(input[radio]): explain what happens with same name on multiple inputs
Closes #15009

Closes #16478
2018-03-12 16:32:23 +02:00
Martin Staffa 85286bd863 docs($http): move response object documentation into Usage section 2018-03-07 11:27:09 +01:00
Martin Staffa 1faf7ec30d fix($http): set correct xhrStatus in response when using 'timeout'
This correctly sets "timeout" if a request fails because the timeout
(numerical or $timeout) is exceeded,
and "abort" if the request is aborted by resolving a promise that was passed in.
2018-03-07 11:27:06 +01:00
Martin Staffa 20724da544 chore(docs.angularjs.org): add csp headers for csp example
Fixes #16270
2018-03-01 16:57:59 +01:00
Martin Staffa 3964598bcf chore(docs-app): add dynamic 404 behavior
Adapted from https://github.com/angular/angular/commit/88045a50506adfe32c2f7a213c8e95f46d1e40e1,
https://github.com/angular/angular/commit/c3fb820473d64036ef0dd3d4c004cc7fbc67be75,
and https://github.com/angular/angular/commit/5a624fa1be530a1b3479a4cc7f96e5a20a3d64fb.
2018-03-01 16:57:58 +01:00
Martin Staffa cd700f65f4 chore(docs.angularjs.org): only deploy production index.html as entry file
Previously, we rewrote index.html to index-production.html, but Firebase ignored
this, probably because an exact file match always takes priority. This lead
to the problem thatthe root - angularjs.org - didn't include the angular.js source
files from the CDN
2018-03-01 16:57:56 +01:00
Martin Staffa f36f25f17a chore(docs.angularjs.org): allow crawling of examples, don't deploy e2e test files 2018-03-01 16:57:55 +01:00
Martin Staffa fcc26063c5 docs(tutorial): fix headlines 2018-02-27 17:47:31 +01:00
Frederik Prijck 0b66753488 docs(README): fix incorrect version-support-status link (#16473)
Closes #16472
2018-02-26 15:04:51 +01:00
George Kalpakas b30a925d54 refactor($compile): avoid catastrophic backtracking when parsing bindings
This isn't expected to have any actual impact, since AngularJS is only
intended to be used in the browser (not the server) and for this RegExp
to be exploited by malicious user code the developer would have to have
to give the user rights to execute arbitrary JavaScript code anyway.
Fixing as a general good practice and to avoid encouraging use of a
similar RegExp in other environments where it might actually matter.

Closes #16464
2018-02-21 11:50:39 +02:00
Pete Bacon Darwin fe599dbb72 docs(misc): add version-support-status page (#16460)
Closes #16058
Closes #16458
2018-02-21 08:33:59 +00:00
Pete Bacon Darwin a7dfa7cd83 docs($route): add missing error document 2018-02-20 12:20:14 +00:00
Pete Bacon Darwin a19a17e288 docs($parse): add missing error documents 2018-02-20 12:18:10 +00:00
Michał Gołębiowski-Owczarek b3224671fb docs(*): add CODE_OF_CONDUCT.md
Closes #16456
2018-02-15 14:37:39 +01:00
Martin Staffa 2953e47da4 chore(docs.angularjs.org): allow crawling but not indexing of partials/
The sitemap.xml might also prevent the indexing, as the partials are not
listed.

Related to #16432 
Closes #16457
2018-02-15 11:54:14 +01:00
Martin Staffa 96bee0c659 chore(docs.angularjs.org): allow robots access to js files
Related to #16432
2018-02-13 10:17:04 +01:00
George Kalpakas 5b87647243 chore(travis): re-enable test jobs 2018-02-13 02:20:22 +02:00
George Kalpakas 6f10c2d9d1 chore(travis): fix ROOT_DIR path when build.sh is sourced 2018-02-13 01:52:02 +02:00
George Kalpakas 76882169ba chore(travis): temporarily disable test jobs 2018-02-13 01:39:26 +02:00
George Kalpakas f93c770cc2 chore(docs.angularjs.org): install firebase dependencies before deploying
Firebase is trying to execute our functions code locally in order to
parse the triggers. Install npm dependencies to avoid errors like:

```
Error: Error parsing triggers: Cannot find module 'firebase-functions'
```

Closes #16453
2018-02-13 01:37:37 +02:00
George Kalpakas 06f5069813 chore(docs.angular.js): do not break when deploying
Follow-up to #16451.

Closes #16452
2018-02-12 23:21:23 +02:00
Martin Staffa 8681fce27b chore(docs.angularjs.org): serve snapshots for googlebot
This commit restores serving the plain partials (content) when a docs
page is accessed with ?_escaped_fragment_=.
The Google Ajax Crawler accesses these urls when the page has
`<meta type="fragment" content="!">` is set.

During the migration to Firebase, this was lost, which resulted in Google
dropping the docs almost completely from the index.

We are using a Firebase cloud function to serve the partials. Since
we cannot access the static hosted files from the function, we have to
deploy them as part of the function directory instead, from which they
can be read.

Related to #16432
Related to #16417
2018-02-12 16:09:54 +01:00
Martin Staffa 5a022524a3 chore(deploy): rename deploy folders 2018-02-12 16:09:52 +01:00
Martin Staffa 5acfac894c chore(code.angularjs.org): don't gzip compressed image files 2018-02-12 16:09:51 +01:00
Martin Staffa a879e82a9b chore(eslint): allow ES6 for node scripts 2018-02-12 16:09:49 +01:00
George Kalpakas c03fda012a fix(docs): fix @media breakpoints for small/extra small devices
Previously, our custom styles used `@media` breakpoints for
small/extra small devices that were off-by-one from
[Bootstrap breakpoints](https://getbootstrap.com/docs/3.3/css/#responsive-utilities-classes)
(767px vs 768px). This caused the site to not be displayed correctly on
these exact sizes, which affected for example all iPad devices (whose
screens are exactly 768px wide).

This commit fixes it by making our breakpoints match those of Bootstrap.

Fixes #16448

Closes #16449
2018-02-11 21:24:18 +02:00
Martin Staffa 976e34bab6 test(input): add test for IE composition bug 2018-02-08 23:51:37 +01:00
Jae Ik Lee 9a1b7c9fa1 fix(input): fix composition mode in IE for Korean input
Fixes #6656
Closes #16273
2018-02-08 23:51:34 +01:00
Martin Staffa c33fd13254 fix(browserTrigger): support CompositionEvent 2018-02-08 23:51:31 +01:00
Martin Staffa 336bad182f chore(docs.angularjs.org): deploy sitemap.xml
Closes #16445
2018-02-08 23:43:00 +01:00
Martin Staffa 553ca78406 chore(code.angularjs.org): increase the cache duration
This is already set, but wasn't checked in
2018-02-08 19:00:42 +01:00
frederikprijck 0722ab0ba1 docs(ngClass): add docs regarding animation for ngClassEven and ngClassOdd
Previously, the documentation has no information regarding using
`ngAnimate` together with the `ngClassEven` and `ngClassOdd` directives.

This commit adds the same docs used by the `ngClass` directive to the
`ngClassEven` and `ngClassOdd` docs and adds an extra example for both
`ngClassEven` and `ngClassOdd` that showcases animations.

Closes #15654
2018-02-06 21:59:26 +02:00
Maksim Ryzhikov ee8e05cfaf feat($sanitize): support enhancing elements/attributes white-lists
Fixes #5900
Closes #16326
2018-02-06 16:09:14 +02:00
Martin Staffa 9509feba99 chore(docs.angularjs.org): fix incorrect rewrites 2018-02-05 22:18:03 +01:00
Martin Staffa b0b3a2b6cb chore(docs.angularjs.org): serve xml files (sitemap) 2018-02-05 19:26:19 +01:00
Martin Staffa 3abe5b77b3 chore(docs.angularjs.org): allow robots to access js and css
Otherwise, the google bot cannot execute the JS
2018-02-05 17:53:55 +01:00
Martin Staffa 858807ad5d chore(code.angularjs.org): fix robots.txt
- allow all-versions-data.js in snapshot, which is used by docs.angularjs.org
- disallow access to folders like docs-0.9.2 etc which are used by early versions
2018-02-05 17:53:49 +01:00
Martin Staffa 7436063a7d chore(doc-gen): generate sitemap.xml 2018-02-05 17:53:46 +01:00
Martin Staffa d1bc780304 chore(docs-gen): generate list of versions in correct order
Closes #16419
2018-02-05 16:29:44 +01:00
Martin Staffa 28f273e473 chore(code.angularjs.org): improve output of directory listing 2018-02-05 16:29:06 +01:00
Martin Staffa 1cdc72f3a5 chore(docs.angularjs.org): add robots.txt 2018-02-02 12:31:49 +01:00
Martin Staffa c3c5c5eea2 docs(changelog): add changes for 1.6.9 2018-02-02 11:19:32 +01:00
Peter Bacon Darwin 4cc7701700 docs(*): ensure naming is correct for Angular(JS) versions
This was originally done on the master branch in
commit 03043839d5,
but never back-ported to 1.6.x.

That wasn't a big deal because docs.angularjs.org
served the master snapshot docs. However, now we
serve the 1.6.x snapshot docs, and it looks strange
that the official docs have the wrong branding :).
2018-02-02 11:10:17 +01:00
Dmitriy 5dc07667de feat(input): add drop event support (#16420) 2018-01-28 11:27:43 +00:00
Martin Staffa 212e5132ab chore(docs.angularjs.org): actually fix deployment
When a file is symlinked, relative paths obviously aren't correct anymore.
This error was masked because Travis didn't fail the job when Firebase
couldn't find the public folder.
To fix, we copy the file and adjust the folder path
2018-01-25 19:35:04 +01:00
Martin Staffa 00162655e7 docs(*): fix headings, links, and wordings 2018-01-25 19:31:40 +01:00
Martin Staffa 09f1325065 chore(docs.angularjs.org): fix firebase deploy
Travis looks for the firebase.json in the repo root,
but we moved each firebase project in its own sub-folder.
To fix, we create a symlink before deployment.
2018-01-22 17:19:55 +01:00
Martin Staffa c01dad694d chore(code.angularjs.org): don't use trailing slashes, and don't set headers after response was sent 2018-01-22 16:00:39 +01:00
Martin Staffa c4586513d1 chore(code.angularjs.org): don't gzip the zip file before uploading 2018-01-22 16:00:39 +01:00
Martin Staffa 7a1270cf4b chore(errors.angularjs.org): add project with redirects to docs.angularjs.org 2018-01-22 16:00:39 +01:00
Martin Staffa 559e93c7ce chore(docs.angularjs.org): move project in separate folder
Firebase projects should be in their own folder, because the firebase-tools
search for projects in the parent folder, which makes it more difficult to create
new projects.
2018-01-22 16:00:38 +01:00
Pete Bacon Darwin 9d058de04b fix(ngMessages): prevent memory leak from messages that are never attached
Closes #16389
Closes #16404
Closes #16406
2018-01-17 16:05:07 +01:00
Martin Staffa 1d826e2f1e fix(ngTransclude): remove terminal: true
This was introduced in commit 2adaff083f,
but made obsolete in 41f3269bfb.

Fixes #16411
Closes #16412
2018-01-17 16:05:07 +01:00
Martin Staffa 5789094546 docs(ngRepeat): improve info about tracking
- deduplicate info between docs section and arguments
- don't draw too much attention to track by $index  ...
- ... but highlight its drawbacks
- add example to show how tracking affects collection updates
- clarify duplicates support for specific tracking expressions

Closes #16332
Closes #16334 
Closes #16397
2018-01-17 16:05:07 +01:00
Martin Staffa cf92c33a32 docs(*): clarify module API and dependency injection rules
Closes #16363
Closes #16395
2018-01-17 16:05:07 +01:00
Martin Staffa 5d8f5a8be7 chore(code.angularjs.org): resolve gcs file stream on 'finish'
'response' is called before the data transfer is complete.
2018-01-17 16:05:07 +01:00
Martin Staffa 74a2808487 chore(docs.angularjs.org): copy unminified angular files
e2e tests use the unminified files even in production deployment
2018-01-17 16:05:07 +01:00
Deb Saunders 9ba181b80f docs(guide/External Resources): remove link to deprecated content
Content at URL is deprecated.

Closes #16403
2018-01-17 16:05:07 +01:00
Frederik Prijck 44c16b5b51 docs(guide/Animations): fix minor typos
Closes #16409
2018-01-17 16:05:07 +01:00
Manuel Darveau 70a42fcaee docs(guide/Using $location): fix typo
Closes #16408
2018-01-17 16:05:07 +01:00
Martin Staffa 3bd62d2d59 chore(node): add karma launchers for Edge, IE, and Safari
That makes it easier to run the tests with these browsers locally.

Closes #16407
2018-01-17 16:05:07 +01:00
Peter Bacon Darwin b9ef6585e1 fix($sanitize): sanitize xml:base attributes
On Firefox there is a XSS vulnerability if a malicious attacker
can write into the `xml:base` attribute on an SVG anchor.

Thanks to Masato Kinugawa at Cure23
2018-01-17 16:05:07 +01:00
Martin Staffa e06b4fb62c chore(travis): test on 2 latest Safari versions 2018-01-17 16:05:07 +01:00
Martin Staffa 9204a1a153 test(*): fix tests for Safari 10+
The mocksSpec change is due to the following issue in Safari 10+ strict mode:
In the following code, Safari will not use the name of the enclosing function (testCaller)
in the stack, but rather list the anonymous function that is called to inject:

```
function testCaller() {
  return inject(function() {
    throw new Error();
  });
}
var throwErrorFromInjectCallback = testCaller();
```

Naming the anonymous function allows us to check for it in the test.
2018-01-17 16:05:07 +01:00
Martin Staffa f4d49f3769 docs(guide/Controllers): fix headings; re-order info 2018-01-10 13:01:33 +01:00
Martin Staffa d5c35b44d7 chore(node): update semver
Closes #16396
2018-01-10 12:58:52 +01:00
Martin Staffa 551375c736 docs(vendor): add readme 2018-01-08 13:03:36 +01:00
Martin Staffa 17691790e9 refactor(getVersion.js): remove unused parameters
The parameters have been unused since we moved most of the bower
package dependencies to npm
2018-01-08 13:03:24 +01:00
Michał Gołębiowski-Owczarek e47dead052 chore(*): get rid of Bower in favor of Yarn aliases & checked-in packages
Bower was used to install multiple versions of jQuery which is now handled
using Yarn aliases. The remaining two packages, closure-compiler and
ng-closure-compiler were installed from zip files which is not supported by Yarn
(see https://github.com/yarnpkg/yarn/issues/1483); the first of them exists
on npm as the google-closure-compiler but only versions newer than we used are
published and they don't work with ng-closure-compiler so - instead - both were
checked in to the repository.

Fixes #16268
Fixes #14961
Ref yarnpkg/yarn#1483
2018-01-08 13:03:20 +01:00
Martin Staffa 1a2532601b chore(node): update karma to 2.0.0
Also reduce karma log level on Travis to INFO.
Before, the log level was DEBUG, but it seems that
prior to karma 2.0.0, the debug messages were not outoput on Karma,
so this simply restores the status quo (and prevents cluttering the log).
2018-01-08 10:43:12 +01:00
Martin Staffa cb862aaaa0 chore(node): update jasmine to 2.8.0, and adjust tests 2018-01-08 10:43:11 +01:00
Martin Staffa fa2034c167 test($sanitize): skip nextSibling clobber test on Edge 16
In some circumstances, Edge 16 will not throw on clobbered
elements, because the nextSibling property is null. The exact
cause is currently unknown.
2018-01-08 10:43:10 +01:00
Martin Staffa 750b43b6f6 chore(*): update copyright year
Closes #16386
2018-01-05 21:07:32 +01:00
Martin Staffa 048f5e3ab8 docs(DEVELOPERS.md): improve testing section 2018-01-05 21:07:26 +01:00
Sergey Kryvets 13c566cc03 docs(developers.md): update node version as specified in package.json
Closes #16384
2018-01-05 21:07:19 +01:00
Georgii Dolzhykov 45834eac09 docs(ngModel.NgModelController): correct description for $viewChangeListeners
It was misleading.

Closes #16382
2018-01-05 21:07:13 +01:00
Georgios Kalpakas 3673909896 feat(currencyFilter): trim whitespace around an empty currency symbol
In most locales, this won't make a difference (since they do not have
whitespace around their currency symbols). In locales where there is a
whitespace separating the currency symbol from the number, it makes
sense to also remove such whitespace if the user specified an empty
currency symbol (indicating they just want the number).

Fixes #15018
Closes #15085

Closes #15105
2017-12-19 11:32:05 +02:00
Martin Staffa 8302981a08 docs(CHANGELOG.md): add changes for 1.6.8 2017-12-18 15:17:56 +01:00
Martin Staffa d2a7b5162f docs(*): add browserTrigger docs; update references to scenario runner 2017-12-18 15:06:21 +01:00
Jason Bedard 2ecd85b989 test($rootScope): test recursive event broadcast and emit 2017-12-18 15:06:20 +01:00
Peter Bacon Darwin 2bdf712687 fix($location): always decode special chars in $location.url(value)
The original fix for #16312 included changing how `$location.url(value)`
decoded the special characters passed to it as a setter.
This broke a number of use cases (mostly involving the ui-router).

Further analysis appears to show that we can solve #16312, to prevent
urls being rewritten with decoded values, without modifying the
behaviour of `$location.url`.

This commit reverts changes to `$location.url(value)` so that encoded
chars will once again be decoded and passed to `$location.path(value)`.
In particular it will convert encoded forward slashes, which changes how
the path is updated, since e.g. `a/b/%2Fc%2Fd` will become `a/b/c/d`.
While this is arguably not "correct", it appears that there are too many
use cases relying upon this behaviour.
2017-12-11 19:41:38 +00:00
John Hampton 0de02973c1 docs(ng-model-options): remove extra quotes in example
Remove unnecessary quotes around attribute directive name in the docs example.  This syntax is incorrect.

Closes #16362
2017-12-11 10:57:46 +02:00
Martin Staffa 55516da2df fix(ngModelController): allow $overrideModelOptions to set updateOn
Also adds more docs about "default" events and how to override
ngModelController options.

Closes #16351
Closes #16364
2017-12-08 11:11:42 +01:00
Michał Gołębiowski-Owczarek e8adbf8d5a chore(*): bump Yarn in Jenkins init-node script
Without it Jenkins builds are broken.

Closes #16365
2017-12-07 20:28:02 +01:00
Michał Gołębiowski-Owczarek c169c60535 build(*): update Node from 6 to 8, update Yarn
Angular (2+) switched to Node 8 and so should we.

Closes #16360
Ref angular/angular#20807
Ref angular/angular#20832
2017-12-07 19:27:40 +01:00
Jason Bedard 0b6ec6b3ab refactor($rootScope): consistently use noop as the default $watch listener
Closes #16343
2017-12-07 11:14:29 +01:00
Martin Staffa d2511cfac0 chore(travis): fix deployment condition to include tagged commits
Tagged commits are not considered to belong to any branch.

Closes #16346
2017-12-07 11:13:09 +01:00
jugglinmike 155efa421b docs(ngNonBindable): document effect on the element's directives
The phrase "contents of the current DOM element" may be interpreted either as
inclusive of the DOM element's attributes or as exclusive of the attributes.
This situation concerns markup such as:

    <div ng-non-bindable ng-controller="MyController"></div>

In practice, AngularJS does not compile or bind attribute values for elements
which specify the `ng-non-bindable` directive. Extend the documentation to
definitely describe this behavior.

Closes #16338
2017-12-07 11:13:09 +01:00
Francesco Pipita f33d95cfcf feat($parse): add a hidden interface to retrieve an expression's AST
This PR adds a new private method to the `$parse` service, `$$getAst`,
which takes an Angular expression as its only argument and returns
the computed AST. This feature is not meant to be part of the public
API and might be subject to changes, so use it with caution.

Closes #16253

Closes #16260
2017-11-30 16:33:19 +02:00
Peter Bacon Darwin 57b626a673 fix($location): decode non-component special chars in Hashbang URLS
Fixes https://github.com/angular/angular.js/pull/16316#issuecomment-347527097
2017-11-30 13:23:16 +00:00
268 changed files with 14167 additions and 3977 deletions
+1 -1
View File
@@ -1,4 +1,3 @@
bower_components/**
build/**
docs/bower_components/**
docs/app/assets/js/angular-bootstrap/**
@@ -9,3 +8,4 @@ src/angular.bind.js
src/ngParseExt/ucd.js
i18n/closure/**
tmp/**
vendor/**
+7 -2
View File
@@ -1,8 +1,13 @@
{
"extends": "./.eslintrc-base.json",
"env": {
"browser": false,
"node": true
}
},
"parserOptions": {
"ecmaVersion": 2017
},
"plugins": [
"promise"
]
}
+2 -3
View File
@@ -1,4 +1,5 @@
/build/
/deploy/
/benchpress-build/
.DS_Store
gen_docs.disable
@@ -10,7 +11,6 @@ performance/temp*.html
*.swp
angular.js.tmproj
node_modules/
bower_components/
angular.xcodeproj
.idea
*.iml
@@ -19,7 +19,6 @@ angular.xcodeproj
libpeerconnection.log
npm-debug.log
/tmp/
/scripts/bower/bower-*
.vscode
*.log
*.stackdump
*.stackdump
+1 -1
View File
@@ -1 +1 @@
6
8
+7 -8
View File
@@ -1,12 +1,10 @@
language: node_js
sudo: false
node_js:
- '6'
- '8'
cache:
yarn: true
directories:
- bower_components
branches:
except:
@@ -28,11 +26,11 @@ env:
- secure: oTBjhnOKhs0qDSKTf7fE4f6DYiNDPycvB7qfSF5QRIbJK/LK/J4UtFwetXuXj79HhUZG9qnoT+5e7lPaiaMlpsIKn9ann7ffqFWN1E8TMtpJF+AGigx3djYElwfgf5nEnFUFhwjFzvbfpZNnxVGgX5YbIZpe/WUbHkP4ffU0Wks=
before_install:
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 0.27.5
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.3.2
- export PATH="$HOME/.yarn/bin:$PATH"
before_script:
- du -sh ./node_modules ./bower_components/ || true
- du -sh ./node_modules || true
- "./scripts/travis/before_build.sh"
script:
@@ -54,10 +52,10 @@ notifications:
jobs:
include:
- stage: deploy
# Don't deploy from PRs and only from our default branches.
# Don't deploy from PRs. Only deploy from our default branches, or if commit is tagged.
# This is a Travis-specific boolean language: https://docs.travis-ci.com/user/conditional-builds-stages-jobs#Specifying-conditions
# The deployment logic for pushed branches is further defined in scripts\travis\build.sh
if: type != pull_request and branch =~ ^(v1\.\d+\.x|master)$
if: type != pull_request and (branch =~ ^(v1\.\d+\.x|master)$ or tag IS present)
env:
- JOB=deploy
before_script: skip
@@ -84,6 +82,7 @@ jobs:
- provider: firebase
# the upload folder for firebase is configured in /firebase.json
skip_cleanup: true
project: docs-angularjs-org-9p2
token:
secure: $FIREBASE_TOKEN
on:
@@ -96,7 +95,7 @@ jobs:
secret_access_key:
secure: tHIFdSq55qkyZf9zT/3+VkhUrTvOTMuswxXU3KyWaBrSieZqG0UnUDyNm+n3lSfX95zEl/+rJAWbfvhVSxZi13ndOtvRF+MdI1cvow2JynP0aDSiPffEvVrZOmihD6mt2SlMfhskr5FTduQ69kZG6DfLcve1PPDaIwnbOv3phb8=
bucket: code-angularjs-org-338b8.appspot.com
local-dir: uploadCode
local-dir: deploy/code
detect_encoding: true # detects gzip compression
on:
repo: angular/angular.js
+102
View File
@@ -1,3 +1,105 @@
<a name="1.6.10"></a>
# 1.6.10 crystalline-persuasion (2018-04-17)
## Bug Fixes
- **$compile:**
- correctly handle `null`/`undefined` href `attrs.$set()`
([f04e04](https://github.com/angular/angular.js/commit/f04e04e0e63e0d30c29718abd5cae634901793b2),
[#16520](https://github.com/angular/angular.js/issues/16520))
- throw error in `$onChanges` immediately
([b7d1e0fbd](https://github.com/angular/angular.js/commit/983e27b628fd1eab653e2b3966d90a270f27cc93),
[#15578](https://github.com/angular/angular.js/issues/15578),
[#16492](https://github.com/angular/angular.js/issues/16492))
- **input:**
- allow overriding timezone for date input types
([4355de](https://github.com/angular/angular.js/commit/4355dee21d26667bb7f6f21bf75c081351315033),
[#16181](https://github.com/angular/angular.js/issues/16181),
[#13382](https://github.com/angular/angular.js/issues/13382),
[#16336](https://github.com/angular/angular.js/issues/16336))
- take timezone into account when validating minimum and maximum in date types
([2f0ac6](https://github.com/angular/angular.js/commit/2f0ac696cb09aec3e291bb8c9c8a1092cbe3a061),
[#16342](https://github.com/angular/angular.js/issues/16342),
[#16390](https://github.com/angular/angular.js/issues/16390))
- fix composition mode in IE for Korean input
([9a1b7c](https://github.com/angular/angular.js/commit/9a1b7c9fa135d1dae3f9b4ccf48f081675796e92),
[#6656](https://github.com/angular/angular.js/issues/6656),
[#16273](https://github.com/angular/angular.js/issues/16273))
- **jqLite:** use XHTML-compliant HTML as input for jqLite
([a0c55a](https://github.com/angular/angular.js/commit/a0c55af9858075ab268a88dd7a4464788a46f4b7),
[#6917](https://github.com/angular/angular.js/issues/6917),
[#16518](https://github.com/angular/angular.js/issues/16518))
- **minErr:** update url to https
([52e466](https://github.com/angular/angular.js/commit/52e46683bfcc0ce0dc9a3d2ee42b389508423799))
- **$http:** set correct xhrStatus in response when using 'timeout'
([1faf7e](https://github.com/angular/angular.js/commit/1faf7ec30d55bba107b18efbcf0ef07732c55b91))
- **browserTrigger:** support CompositionEvent
([c33fd1](https://github.com/angular/angular.js/commit/c33fd1325417fdc6d7d6abc90cd935130653b149))
## New Features
- **$http:** support sending XSRF token to whitelisted origins
([bc7757](https://github.com/angular/angular.js/commit/bc775759c88b2221c2bb71d2335bc233c93f43b0),
[#7862](https://github.com/angular/angular.js/issues/7862))
- **minErr:** strip error url from error parameters
([980b69](https://github.com/angular/angular.js/commit/980b69dcae73dd8a3d0b9d91b63fa7711cd0ba36))
- **$sanitize:** support enhancing elements/attributes white-lists
([ee8e05](https://github.com/angular/angular.js/commit/ee8e05cfafe086188fc318ed4115fb56ba335112),
[#5900](https://github.com/angular/angular.js/issues/5900),
[#16326](https://github.com/angular/angular.js/issues/16326))
- **$rootScope:** allow suspending and resuming watchers on scope
([efb822c58](https://github.com/angular/angular.js/commit/41d5c90f170cc054b0f8f88220c22ef1ef6cc0a6),
[#16308](https://github.com/angular/angular.js/issues/5301))
<a name="1.6.9"></a>
# 1.6.9 fiery-basilisk (2018-02-02)
## Bug Fixes
- **input:** add `drop` event support for IE
([5dc076](https://github.com/angular/angular.js/commit/5dc07667de00c5e85fd69c5b7b7fe4fb5fd65a77))
- **ngMessages:** prevent memory leak from messages that are never attached
([9d058d](https://github.com/angular/angular.js/commit/9d058de04bb78694b83179e9b97bc40214eca01a),
[#16389](https://github.com/angular/angular.js/issues/16389),
[#16404](https://github.com/angular/angular.js/issues/16404),
[#16406](https://github.com/angular/angular.js/issues/16406))
- **ngTransclude:** remove terminal: true
([1d826e](https://github.com/angular/angular.js/commit/1d826e2f1e941d14c3c56d7a0249f5796ba11f85),
[#16411](https://github.com/angular/angular.js/issues/16411),
[#16412](https://github.com/angular/angular.js/issues/16412))
- **$sanitize:** sanitize `xml:base` attributes
([b9ef65](https://github.com/angular/angular.js/commit/b9ef6585e10477fbbf912a971fe0b390bca692a6))
## New Features
- **currencyFilter:** trim whitespace around an empty currency symbol
([367390](https://github.com/angular/angular.js/commit/3673909896efb6ff47546caf7fc61549f193e043),
[#15018](https://github.com/angular/angular.js/issues/15018),
[#15085](https://github.com/angular/angular.js/issues/15085),
[#15105](https://github.com/angular/angular.js/issues/15105))
<a name="1.6.8"></a>
# 1.6.8 beneficial-tincture (2017-12-18)
## Bug Fixes
- **$location:**
- always decode special chars in `$location.url(value)`
([2bdf71](https://github.com/angular/angular.js/commit/2bdf7126878c87474bb7588ce093d0a3c57b0026))
- decode non-component special chars in Hashbang URLS
([57b626](https://github.com/angular/angular.js/commit/57b626a673b7530399d3377dfe770165bec35f8a))
- **ngModelController:** allow $overrideModelOptions to set updateOn
([55516d](https://github.com/angular/angular.js/commit/55516da2dfc7c5798dce24e9fa930c5ac90c900c),
[#16351](https://github.com/angular/angular.js/issues/16351),
[#16364](https://github.com/angular/angular.js/issues/16364))
## New Features
- **$parse:** add a hidden interface to retrieve an expression's AST
([f33d95](https://github.com/angular/angular.js/commit/f33d95cfcff6fd0270f92a142df8794cca2013ad),
[#16253](https://github.com/angular/angular.js/issues/16253),
[#16260](https://github.com/angular/angular.js/issues/16260))
<a name="1.6.7"></a>
# 1.6.7 imperial-backstroke (2017-11-24)
+3
View File
@@ -0,0 +1,3 @@
# Contributor Code of Conduct
The AngularJS project follows the Code of Conduct defined in [the angular/code-of-conduct repository](https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md). Please read it.
+1 -1
View File
@@ -49,6 +49,7 @@ If you find a bug in the source code, you can help us by submitting an issue to
**Special Note for Localization Issues:** AngularJS uses the [Google Closure I18N library] to
generate its own I18N files (the ngLocale module). This means that any changes to these files
would be lost the next time that we import the library.
Since the Closure library i18n data is itself auto-generated from the data of the
[Common Locale Data Repository (CLDR)] project, errors in the data should
be reported there. See also the [Closure guide to i18n changes].
@@ -164,7 +165,6 @@ restarted.
* Re-run the AngularJS test suite to ensure tests are still passing.
* Commit your changes to your branch (e.g. `my-fix-branch`).
* Push the changes to your GitHub repository (this will update your Pull Request).
You can also amend the initial commits and force push them to the branch.
```shell
+13 -10
View File
@@ -1,6 +1,7 @@
# Developing AngularJS
* [Development Setup](#setup)
* [Running Tests](#tests)
* [Coding Rules](#rules)
* [Commit Message Guidelines](#commits)
* [Writing Documentation](#documentation)
@@ -8,7 +9,7 @@
## <a name="setup"> Development Setup
This document describes how to set up your development environment to build and test AngularJS, and
explains the basic mechanics of using `git`, `node`, `yarn`, `grunt`, and `bower`.
explains the basic mechanics of using `git`, `node`, `yarn` and `grunt`.
### Installing Dependencies
@@ -18,7 +19,7 @@ machine:
* [Git](http://git-scm.com/): The [Github Guide to
Installing Git][git-setup] is a good source of information.
* [Node.js v6.x (LTS)](http://nodejs.org): We use Node to generate the documentation, run a
* [Node.js v8.x (LTS)](http://nodejs.org): We use Node to generate the documentation, run a
development web server, run tests, and generate distributable files. Depending on your system,
you can install Node either from source or as a pre-packaged bundle.
@@ -63,10 +64,10 @@ cd angular.js
# Add the main AngularJS repository as an upstream remote to your repository:
git remote add upstream "https://github.com/angular/angular.js.git"
# Install node.js dependencies:
# Install JavaScript dependencies:
yarn install
# Build AngularJS (which will install `bower` dependencies automatically):
# Build AngularJS:
yarn grunt package
```
@@ -107,6 +108,8 @@ HTTP server. For this purpose, we have made available a local web server based o
http://localhost:8000/build/docs/
```
## <a name="tests"> Running Tests
### <a name="unit-tests"></a> Running the Unit Test Suite
We write unit and integration tests with Jasmine and execute them with Karma. To run all of the
@@ -116,7 +119,7 @@ tests once on Chrome run:
yarn grunt test:unit
```
To run the tests on other browsers (Chrome, ChromeCanary, Firefox and Safari are pre-configured) use:
To run the tests on other browsers use the command line flag:
```shell
yarn grunt test:unit --browsers=Chrome,Firefox
@@ -125,15 +128,15 @@ yarn grunt test:unit --browsers=Chrome,Firefox
**Note:** there should be _no spaces between browsers_. `Chrome, Firefox` is INVALID.
If you have a Saucelabs or Browserstack account, you can also run the unit tests on these services
via our pre-defined customLaunchers.
via our pre-defined customLaunchers. See the [karma config file](/karma-shared.conf.js) for all pre-configured browsers.
For example, to run the whole unit test suite:
For example, to run the whole unit test suite on selected browsers:
```shell
# Browserstack
yarn grunt test:unit --browsers=BS_Chrome,BS_Firefox,BS_Safari,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_8,BS_iOS_9,BS_iOS_10
yarn grunt test:unit --browsers=BS_Chrome,BS_Firefox,BS_Safari,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_10
# Saucelabs
yarn grunt test:unit --browsers=BS_Chrome,BS_Firefox,BS_Safari,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_8,BS_iOS_9,BS_iOS_10
yarn grunt test:unit --browsers=SL_Chrome,SL_Firefox,SL_Safari,SL_IE_9,SL_IE_10,SL_IE_11,SL_EDGE,SL_iOS_10
```
Running these commands requires you to set up [Karma Browserstack][karma-browserstack] or
@@ -483,4 +486,4 @@ You can see an example of a well-defined example [in the `ngRepeat` documentatio
[karma-browserstack]: https://github.com/karma-runner/karma-browserstack-launcher
[karma-saucelabs]: https://github.com/karma-runner/karma-sauce-launcher
[unit-testing]: https://docs.angularjs.org/guide/unit-testing
[yarn-install]: https://yarnpkg.com/en/docs/install
[yarn-install]: https://yarnpkg.com/en/docs/install
+44 -10
View File
@@ -13,6 +13,8 @@ var semver = require('semver');
var exec = require('shelljs').exec;
var pkg = require(__dirname + '/package.json');
var docsScriptFolder = 'scripts/docs.angularjs.org-firebase';
// Node.js version checks
if (!semver.satisfies(process.version, pkg.engines.node)) {
reportOrFail('Invalid node version (' + process.version + '). ' +
@@ -162,7 +164,12 @@ module.exports = function(grunt) {
clean: {
build: ['build'],
tmp: ['tmp']
tmp: ['tmp'],
deploy: [
'deploy/docs',
'deploy/code',
docsScriptFolder + '/functions/html'
]
},
eslint: {
@@ -173,6 +180,7 @@ module.exports = function(grunt) {
'docs/**/*.js',
'lib/**/*.js',
'scripts/**/*.js',
'!scripts/*/*/node_modules/**',
'src/**/*.js',
'test/**/*.js',
'i18n/**/*.js',
@@ -324,19 +332,44 @@ module.exports = function(grunt) {
}
]
},
deployFirebaseCode: {
files: [
// copy files that are not handled by compress
{
cwd: 'build',
src: '**/*.{zip,jpg,jpeg,png}',
dest: 'deploy/code/' + deployVersion + '/',
expand: true
}
]
},
deployFirebaseDocs: {
files: [
// The source files are needed by the embedded examples in the docs app.
{
src: 'build/angular*.{js.map,min.js}',
dest: 'uploadDocs/',
src: ['build/angular*.{js,js.map,min.js}', 'build/sitemap.xml'],
dest: 'deploy/docs/',
expand: true,
flatten: true
},
{
cwd: 'build/docs',
src: '**',
dest: 'uploadDocs/',
src: ['**', '!ptore2e/**', '!index*.html'],
dest: 'deploy/docs/',
expand: true
},
{
src: 'build/docs/index-production.html',
dest: 'deploy/docs/index.html'
},
{
src: 'build/docs/index-production.html',
dest: docsScriptFolder + '/functions/content/index.html'
},
{
cwd: 'build/docs',
src: 'partials/**',
dest: docsScriptFolder + '/functions/content',
expand: true
}
]
@@ -357,10 +390,11 @@ module.exports = function(grunt) {
options: {
mode: 'gzip'
},
src: ['**'],
// Already compressed files should not be compressed again
src: ['**', '!**/*.{zip,png,jpeg,jpg}'],
cwd: 'build',
expand: true,
dest: 'uploadCode/' + deployVersion + '/'
dest: 'deploy/code/' + deployVersion + '/'
}
},
@@ -439,14 +473,12 @@ module.exports = function(grunt) {
'shell:promises-aplus-tests'
]);
grunt.registerTask('minify', [
'bower',
'clean',
'build',
'minall'
]);
grunt.registerTask('webserver', ['connect:devserver']);
grunt.registerTask('package', [
'bower',
'validate-angular-files',
'clean',
'buildall',
@@ -462,9 +494,11 @@ module.exports = function(grunt) {
'merge-conflict',
'eslint'
]);
grunt.registerTask('prepareFirebaseDeploy', [
grunt.registerTask('prepareDeploy', [
'package',
'compress:deployFirebaseCode',
'copy:deployFirebaseCode',
'firebaseDocsJsonForTravis',
'copy:deployFirebaseDocs'
]);
grunt.registerTask('default', ['package']);
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2010-2017 Google, Inc. http://angularjs.org
Copyright (c) 2010-2018 Google, Inc. http://angularjs.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+1 -1
View File
@@ -7,7 +7,7 @@ in its `contrib/externs` directory.
The definitions contain externs for use with the Closure compiler (aka
JSCompiler). Passing these files to the --externs parameter of a compiler
pass allows using type annotations for AngularJS objects. For example,
Angular's $scope objects can be annotated as:
AngularJS's $scope objects can be annotated as:
```js
/** @type {angular.Scope} */
var scope = $scope;
+9 -2
View File
@@ -12,6 +12,14 @@ It also helps with server-side communication, taming async callbacks with promis
and it makes client-side navigation and deep linking with hashbang urls or HTML5 pushState a
piece of cake. Best of all? It makes development fun!
--------------------
##### AngularJS will be moving to Long Term Support (LTS) mode on July 1st 2018: [Find out more](https://docs.angularjs.org/misc/version-support-status)
##### Looking for the new Angular? Go here: https://github.com/angular/angular
--------------------
* Web site: https://angularjs.org
* Tutorial: https://docs.angularjs.org/tutorial
* API Docs: https://docs.angularjs.org/api
@@ -20,7 +28,6 @@ piece of cake. Best of all? It makes development fun!
* Core Development: [DEVELOPERS.md](DEVELOPERS.md)
* Dashboard: https://dashboard.angularjs.org
##### Looking for Angular 2? Go here: https://github.com/angular/angular
Documentation
--------------------
@@ -72,7 +79,7 @@ HTML is also used to determine the wiring of the app. Special attributes in the
to load the app, which components or controllers to use for each element, etc. We specify "what"
gets loaded, but not "how". This declarative approach greatly simplifies app development in a sort
of WYSIWYG way. Rather than spending time on how the program flows and orchestrating the various
moving parts, we simply define what we want and Angular will take care of the dependencies.
moving parts, we simply define what we want and AngularJS will take care of the dependencies.
#### Data Handling made simple
Data and Data Models in AngularJS are plain JavaScript objects and one can add and change properties
+4 -4
View File
@@ -1,6 +1,6 @@
# Triage new issues/PRs on github
This document shows the steps the Angular team is using to triage issues.
This document shows the steps the AngularJS team is using to triage issues.
The labels are used later on for [planning releases](#assigning-work).
@@ -45,12 +45,12 @@ This process based on the idea of minimizing user pain
1. Label `frequency: *` How often does this issue come up? How many developers does this affect? Chose just one of the following:
* low - obscure issue affecting a handful of developers
* moderate - impacts a common usage pattern
* high - impacts most or all Angular apps
* high - impacts most or all AngularJS apps
1. Label `severity: *` - How bad is the issue? Chose just one of the following:
* security issue
* regression
* memory leak
* broken expected use - it's hard or impossible for a developer using Angular to accomplish something that Angular should be able to do
* broken expected use - it's hard or impossible for a developer using AngularJS to accomplish something that AngularJS should be able to do
* confusing - unexpected or inconsistent behavior; hard-to-debug
* inconvenience - causes ugly/boilerplate code in apps
1. Label `component: *`
@@ -95,7 +95,7 @@ You can mention him in the relevant thread like this: `@btford`.
> Thanks for submitting this issue!
> Unfortunately, we don't think this functionality belongs in core.
> The good news is that you could easily implement this as a third-party module and publish it on Bower and/or to the npm repository.
> The good news is that you could easily implement this as a third-party module and publish it to the npm registry.
## Assigning Work
+4 -4
View File
@@ -190,7 +190,7 @@ var angularFiles = {
],
'karma': [
'bower_components/jquery/dist/jquery.js',
'node_modules/jquery/dist/jquery.js',
'test/jquery_remove.js',
'@angularSrc',
'@angularSrcModules',
@@ -228,7 +228,7 @@ var angularFiles = {
],
'karmaJquery': [
'bower_components/jquery/dist/jquery.js',
'node_modules/jquery/dist/jquery.js',
'test/jquery_alias.js',
'@angularSrc',
'@angularSrcModules',
@@ -248,8 +248,8 @@ var angularFiles = {
angularFiles['karmaJquery' + jQueryVersion] = []
.concat(angularFiles.karmaJquery)
.map(function(path) {
if (path.startsWith('bower_components/jquery')) {
return path.replace(/^bower_components\/jquery/, 'bower_components/jquery-' + jQueryVersion);
if (path.startsWith('node_modules/jquery')) {
return path.replace(/^node_modules\/jquery/, 'node_modules/jquery-' + jQueryVersion);
}
return path;
});
+1 -1
View File
@@ -1 +1 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
+1 -1
View File
@@ -1 +1 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
+1 -1
View File
@@ -1 +1 @@
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
-11
View File
@@ -1,11 +0,0 @@
{
"name": "angularjs",
"license": "MIT",
"devDependencies": {
"jquery": "3.2.1",
"jquery-2.2": "jquery#2.2.4",
"jquery-2.1": "jquery#2.1.4",
"closure-compiler": "https://dl.google.com/closure-compiler/compiler-20140814.zip",
"ng-closure-runner": "https://raw.github.com/angular/ng-closure-runner/v0.2.4/assets/ng-closure-runner.zip"
}
}
+11 -3
View File
@@ -713,14 +713,14 @@ ul.events > li {
margin-right: 5px;
}
@media only screen and (min-width: 769px) {
@media only screen and (min-width: 768px) {
[ng-include="partialPath"].ng-hide {
display: block !important;
visibility: hidden;
}
}
@media only screen and (min-width: 769px) and (max-width: 991px) {
@media only screen and (min-width: 768px) and (max-width: 991px) {
.main-body-grid {
margin-top: 160px;
}
@@ -729,7 +729,7 @@ ul.events > li {
}
}
@media only screen and (max-width : 768px) {
@media only screen and (max-width: 767px) {
.picker, .picker select {
width: auto;
display: block;
@@ -934,6 +934,14 @@ toc-container > div > toc-tree > ul > li > toc-tree > ul > li toc-tree > ul li {
font-size: 13px;
}
.dev-status span {
padding: 2px 8px;
border-radius: 5px;
}
.security span { background-color: orange; }
.stable span { background-color: green; color: white; }
.current span { background-color: blue; color: white; }
@media handheld and (max-width:800px), screen and (max-device-width:800px), screen and (max-width:800px) {
.navbar {
min-height: auto;
+4
View File
@@ -0,0 +1,4 @@
User-agent: *
# The map files are not required by the app
Disallow: /*.map$
+1
View File
@@ -9,6 +9,7 @@
},
"globals": {
"angular": false,
/* testabilityPatch / matchers */
"inject": false,
"module": false,
+63
View File
@@ -21,6 +21,9 @@ describe('docs.angularjs.org', function() {
console.log('browser console errors: ' + require('util').inspect(filteredLog));
}
});
browser.ignoreSynchronization = false;
browser.clearMockModules();
});
@@ -102,6 +105,66 @@ describe('docs.angularjs.org', function() {
expect(mainHeader.getText()).toEqual('Oops!');
});
it('should set "noindex" if the page does not exist', function() {
browser.get('build/docs/index-production.html#!/api/does/not/exist');
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
expect(robots.isPresent()).toBe(true);
expect(googleBot.isPresent()).toBe(true);
});
it('should remove "noindex" if the page exists', function() {
browser.get('build/docs/index-production.html#!/api');
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
expect(robots.isPresent()).toBe(false);
expect(googleBot.isPresent()).toBe(false);
});
describe('template request error', function() {
beforeEach(function() {
browser.addMockModule('httpMocker', function() {
angular.module('httpMocker', ['ngMock'])
.run(['$httpBackend', function($httpBackend) {
$httpBackend.whenGET('localhost:8000/build/docs/partials/api.html').respond(500, '');
}]);
});
});
it('should set "noindex" for robots if the request fails', function() {
// index-test includes ngMock
browser.get('build/docs/index-test.html#!/api');
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
expect(robots.isPresent()).toBe(true);
expect(googleBot.isPresent()).toBe(true);
});
});
describe('page bootstrap error', function() {
beforeEach(function() {
browser.addMockModule('httpMocker', function() {
// Require a module that does not exist to break the bootstrapping
angular.module('httpMocker', ['doesNotExist']);
});
});
it('should have "noindex" for robots if bootstrapping fails', function() {
browser.get('build/docs/index.html#!/api').catch(function() {
// get() will fail on AngularJS bootstrap, but if we continue here, protractor
// will assume the app is ready
browser.ignoreSynchronization = true;
var robots = element(by.css('meta[name="robots"][content="noindex"]'));
var googleBot = element(by.css('meta[name="googlebot"][content="noindex"]'));
expect(robots.isPresent()).toBe(true);
expect(googleBot.isPresent()).toBe(true);
});
});
});
});
});
+5 -2
View File
@@ -91,13 +91,16 @@ directivesModule
.component('tocTree', {
template: '<ul>' +
'<li ng-repeat="item in $ctrl.items">' +
'<a ng-href="#{{item.fragment}}">{{item.title}}</a>' +
'<a ng-href="{{ $ctrl.path }}#{{item.fragment}}">{{item.title}}</a>' +
'<toc-tree ng-if="::item.children.length > 0" items="item.children"></toc-tree>' +
'</li>' +
'</ul>',
bindings: {
items: '<'
}
},
controller: ['$location', function TocTreeController($location) {
this.path = $location.path().replace(/^\/?(.+?)(\/index)?\/?$/, '$1');
}]
})
.directive('tocContainer', function() {
return {
+11 -5
View File
@@ -8,6 +8,8 @@ angular.module('DocsController', ['currentVersionData'])
function($scope, $rootScope, $location, $window, $cookies,
NG_PAGES, NG_NAVIGATION, CURRENT_NG_VERSION) {
var errorPartialPath = 'Error404.html';
$scope.navClass = function(navItem) {
return {
active: navItem.href && this.currentPage && this.currentPage.path,
@@ -16,8 +18,6 @@ angular.module('DocsController', ['currentVersionData'])
};
};
$scope.$on('$includeContentLoaded', function() {
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
$window._gaq.push(['_trackPageview', pagePath]);
@@ -26,6 +26,7 @@ angular.module('DocsController', ['currentVersionData'])
$scope.$on('$includeContentError', function() {
$scope.loading = false;
$scope.loadingError = true;
});
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
@@ -35,6 +36,7 @@ angular.module('DocsController', ['currentVersionData'])
var currentPage = $scope.currentPage = NG_PAGES[path];
$scope.loading = true;
$scope.loadingError = false;
if (currentPage) {
$scope.partialPath = 'partials/' + path + '.html';
@@ -50,18 +52,22 @@ angular.module('DocsController', ['currentVersionData'])
} else {
$scope.currentArea = NG_NAVIGATION['api'];
$scope.breadcrumb = [];
$scope.partialPath = 'Error404.html';
$scope.partialPath = errorPartialPath;
}
});
$scope.hasError = function() {
return $scope.partialPath === errorPartialPath || $scope.loadingError;
};
/**********************************
Initialize
***********************************/
$scope.versionNumber = CURRENT_NG_VERSION.full;
$scope.version = CURRENT_NG_VERSION.full + ' ' + CURRENT_NG_VERSION.codeName;
$scope.loading = 0;
$scope.loading = false;
$scope.loadingError = false;
var INDEX_PATH = /^(\/|\/index[^.]*.html)$/;
if (!$location.path() || INDEX_PATH.test($location.path())) {
+5 -1
View File
@@ -22,6 +22,7 @@ module.exports = new Package('angularjs', [
.factory(require('./services/deployments/debug'))
.factory(require('./services/deployments/default'))
.factory(require('./services/deployments/jquery'))
.factory(require('./services/deployments/test'))
.factory(require('./services/deployments/production'))
.factory(require('./inline-tag-defs/type'))
@@ -31,6 +32,7 @@ module.exports = new Package('angularjs', [
.processor(require('./processors/keywords'))
.processor(require('./processors/pages-data'))
.processor(require('./processors/versions-data'))
.processor(require('./processors/sitemap'))
.config(function(dgeni, log, readFilesProcessor, writeFilesProcessor) {
@@ -156,12 +158,14 @@ module.exports = new Package('angularjs', [
generateProtractorTestsProcessor,
generateExamplesProcessor,
debugDeployment, defaultDeployment,
jqueryDeployment, productionDeployment) {
jqueryDeployment, testDeployment,
productionDeployment) {
generateIndexPagesProcessor.deployments = [
debugDeployment,
defaultDeployment,
jqueryDeployment,
testDeployment,
productionDeployment
];
+25
View File
@@ -0,0 +1,25 @@
'use strict';
var exclusionRegex = /^index|examples\/|ptore2e\//;
module.exports = function createSitemap() {
return {
$runAfter: ['paths-computed'],
$runBefore: ['rendering-docs'],
$process: function(docs) {
docs.push({
id: 'sitemap.xml',
path: 'sitemap.xml',
outputPath: '../sitemap.xml',
template: 'sitemap.template.xml',
urls: docs.filter(function(doc) {
return doc.path &&
doc.outputPath &&
!exclusionRegex.test(doc.outputPath);
}).map(function(doc) {
return doc.path;
})
});
}
};
};
+6 -5
View File
@@ -55,9 +55,6 @@ module.exports = function generateVersionDocProcessor(gitData) {
if (missesCurrentVersion) versions.push(currentVersion.version);
// Get the stable release with the highest version
var highestStableRelease = versions.reverse().find(semverIsStable);
versions = versions
.filter(function(versionStr) {
return blacklist.indexOf(versionStr) === -1;
@@ -85,6 +82,9 @@ module.exports = function generateVersionDocProcessor(gitData) {
var latest = sortObject(latestMap, reverse(semver.compare))
.map(function(version) { return makeOption(version, 'Latest'); });
// Get the stable release with the highest version
var highestStableRelease = versions.find(semverIsStable);
// Generate master and stable snapshots
var snapshots = [
makeOption(
@@ -130,14 +130,15 @@ module.exports = function generateVersionDocProcessor(gitData) {
return Object.keys(obj).map(function(key) { return obj[key]; }).sort(cmp);
}
// Adapted from
// https://github.com/kaelzhang/node-semver-stable/blob/34dd29842409295d49889d45871bec55a992b7f6/index.js#L25
function semverIsStable(version) {
var semverObj = semver.parse(version);
var semverObj = version.version;
return semverObj === null ? false : !semverObj.prerelease.length;
}
function createSnapshotStableLabel(version) {
var label = 'v' + version.replace(/.$/, 'x') + '-snapshot';
var label = version.label.replace(/.$/, 'x') + '-snapshot';
return label;
}
+40
View File
@@ -0,0 +1,40 @@
'use strict';
module.exports = function testDeployment(getVersion) {
return {
name: 'test',
examples: {
commonFiles: {
scripts: ['../../../angular.js']
},
dependencyPath: '../../../'
},
scripts: [
'../angular.js',
'../angular-resource.js',
'../angular-route.js',
'../angular-cookies.js',
'../angular-mocks.js',
'../angular-sanitize.js',
'../angular-touch.js',
'../angular-animate.js',
'components/marked-' + getVersion('marked') + '/lib/marked.js',
'js/angular-bootstrap/dropdown-toggle.js',
'components/lunr-' + getVersion('lunr') + '/lunr.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/prettify.js',
'components/google-code-prettify-' + getVersion('google-code-prettify') + '/src/lang-css.js',
'js/current-version-data.js',
'js/all-versions-data.js',
'js/pages-data.js',
'js/nav-data.js',
'js/docs.js'
],
stylesheets: [
'components/bootstrap-' + getVersion('bootstrap') + '/css/bootstrap.css',
'css/prettify-theme.css',
'css/angular-topnav.css',
'css/docs.css',
'css/animations.css'
]
};
};
+5 -6
View File
@@ -4,14 +4,13 @@ var path = require('canonical-path');
/**
* dgService getVersion
* @description
* Find the current version of the bower component (or node module)
* Find the current version of the node module
*/
module.exports = function getVersion(readFilesProcessor) {
var basePath = readFilesProcessor.basePath;
var sourceFolder = path.resolve(readFilesProcessor.basePath, 'node_modules');
var packageFile = 'package.json';
return function(component, sourceFolder, packageFile) {
sourceFolder = path.resolve(basePath, sourceFolder || 'node_modules');
packageFile = packageFile || 'package.json';
return require(path.join(sourceFolder,component,packageFile)).version;
return function(component) {
return require(path.join(sourceFolder, component, packageFile)).version;
};
};
@@ -11,6 +11,18 @@
<meta name="fragment" content="!">
<title ng-bind-template="AngularJS: {{ currentArea.name }}: {{ currentPage.name || 'Error: Page not found'}}">AngularJS</title>
<script type="text/javascript">
(function() {
// Dynamically, pre-emptively, add `noindex`, which will be removed when the doc is ready and valid
['googlebot', 'robots'].forEach(function(bot) {
var tag = document.createElement('meta');
tag.name = bot;
tag.content = 'noindex';
tag.setAttribute('ng-if', 'hasError()');
document.head.appendChild(tag);
});
})();
</script>
<script type="text/javascript">
// dynamically add base tag as well as css and javascript files.
// we can't add css/js the usual way, because some browsers (FF) eagerly prefetch resources
@@ -127,7 +139,7 @@
</ul>
</div>
<div class="search-results-container" ng-show="hasResults">
<div class="search-results-container" ng-show="hasResults" ng-cloak>
<div class="container">
<div class="search-results-frame">
<div ng-repeat="(key, value) in results track by key" class="search-results-group" ng-class="colClassName + ' col-group-' + key" ng-show="value.length > 0">
@@ -157,7 +169,7 @@
</div>
</div>
</nav>
<nav id="navbar-sub" class="sup-header navbar navbar-fixed-top" scroll-y-offset-element>
<nav id="navbar-sub" class="sup-header navbar navbar-fixed-top" scroll-y-offset-element ng-cloak>
<div class="container main-grid main-header-grid">
<div class="grid-left">
<version-picker></version-picker>
@@ -174,7 +186,7 @@
</nav>
</header>
<section role="main" class="container main-body">
<section role="main" class="container main-body" ng-cloak>
<div class="main-grid main-body-grid">
<div class="grid-left">
<a class="btn toc-toggle visible-xs" ng-click="toc=!toc">Show / Hide Table of Contents</a>
@@ -198,7 +210,8 @@
</div>
</div>
<div class="grid-right">
<div id="loading" ng-show="loading">Loading...</div>
<div ng-show="loading">Loading &hellip;</div>
<div ng-show="loadingError">There was an error loading this resource. Please try again later.</div>
<div ng-hide="loading" ng-include="partialPath" toc-collector autoscroll></div>
</div>
</div>
@@ -209,10 +222,10 @@
<p class="pull-right"><a back-to-top>Back to top</a></p>
<p>
Super-powered by Google ©2010-2017
Super-powered by Google ©2010-2018
(<a id="version"
ng-href="https://github.com/angular/angular.js/blob/master/CHANGELOG.md#{{versionNumber}}"
ng-bind-template="v{{version}}" title="Changelog of this version of Angular JS">
ng-bind-template="v{{version}}" title="Changelog of this version of AngularJS">
</a>)
</p>
<p>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{%- for url in doc.urls %}
<url>
<loc>https://docs.angularjs.org/{$ url $}</loc>
</url>{% endfor %}
</urlset>
+14 -6
View File
@@ -3,7 +3,15 @@
@description
# AngularJS API Docs
Welcome to the AngularJS API docs page. These pages contain the AngularJS reference materials for version <strong ng-bind="version"></strong>.
<div class="alert alert-warning">
**AngularJS will be moving to Long Term Support (LTS) mode on July 1st 2018.**: [Find out more](misc/version-support-status).
</div>
## Welcome to the AngularJS API docs page.
These pages contain the AngularJS reference materials for version <strong ng-bind="version"></strong>.
The documentation is organized into **{@link guide/module modules}** which contain various components of an AngularJS application.
These components are {@link guide/directive directives}, {@link guide/services services}, {@link guide/filter filters}, {@link guide/providers providers}, {@link guide/templates templates}, global APIs, and testing mocks.
@@ -11,14 +19,14 @@ These components are {@link guide/directive directives}, {@link guide/services s
There is also a {@link guide/index guide} with articles on various topics, and a list of external resources.
<div class="alert alert-info">
**Angular Prefixes `$` and `$$`**:
**AngularJS Prefixes `$` and `$$`**:
To prevent accidental name collisions with your code,
Angular prefixes names of public objects with `$` and names of private objects with `$$`.
AngularJS prefixes names of public objects with `$` and names of private objects with `$$`.
Please do not use the `$` or `$$` prefix in your code.
</div>
## Angular Modules
## AngularJS Modules
## {@link ng ng (core module)}
@@ -83,7 +91,7 @@ This module is provided by default and contains the core components of AngularJS
</td>
<td>
<p>
The core global API functions are attached to the angular object. These core functions are useful for low level JavaScript operations within your application.
The core global API functions are attached to the `angular` object. These core functions are useful for low level JavaScript operations within your application.
</p>
<p>
Some examples include:
@@ -130,7 +138,7 @@ Use ngRoute to enable URL routing to your application. The ngRoute module suppor
## {@link ngAnimate ngAnimate}
Use ngAnimate to enable animation features within your application. Various core ng directives will provide
Use ngAnimate to enable animation features within your application. Various core AngularJS directives will provide
animation hooks into your application when ngAnimate is included. Animations are defined by using CSS transitions/animations
or JavaScript callbacks.
+1 -1
View File
@@ -5,7 +5,7 @@
This error occurs when the application's model becomes unstable because some `$onChanges` hooks are causing updates which then trigger
further calls to `$onChanges` that can never complete.
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
For example, the situation can occur by setting up a `$onChanges()` hook which triggers an event on the component, which subsequently
triggers the component's bound inputs to be updated:
+1 -1
View File
@@ -11,7 +11,7 @@ value is `JSON_CALLBACK`.
parameter is specified in the configuration object (or in the defaults) via the `jsonpCallbackParam`
property. You must not provide your own parameter with this name in the configuratio of the request.
In previous versions of Angular, you specified where to add the callback parameter value via the
In previous versions of AngularJS, you specified where to add the callback parameter value via the
`JSON_CALLBACK` placeholder. This is no longer allowed.
To resolve this error, remove any parameters that have the same name as the `jsonpCallbackParam`;
+1 -1
View File
@@ -15,7 +15,7 @@ In AngularJS `1.2.0` and later, `ngRoute` has been moved to its own module.
If you are getting this error after upgrading to `1.2.x` or later, be sure that you've
installed {@link ngRoute `ngRoute`}.
### Monkey-patching Angular's `ng` module
### Monkey-patching AngularJS's `ng` module
This error can also occur if you have tried to add your own components to the `ng` module.
This has never been supported and from `1.3.0` it will actually trigger this error.
@@ -3,4 +3,4 @@
@fullName Expecting end operator
@description
The Angular expression is missing the corresponding closing operator.
The AngularJS expression is missing the corresponding closing operator.
@@ -8,4 +8,4 @@ extension in your interpolation expression. The different choices have to be un
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -9,4 +9,4 @@ bug mentioning the exact version of AngularJS used and we will fix it!
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -14,4 +14,4 @@ future commit and the github issue will help gauge urgency.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
+2 -2
View File
@@ -4,9 +4,9 @@
@description
You must specify the MessageFormat function that you're using right after the
comma following the Angular expression. Currently, the supported functions are
comma following the AngularJS expression. Currently, the supported functions are
"plural" and "select" (for gender selections.)
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -8,4 +8,4 @@ extension keyword in the extended interpolation syntax.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -8,4 +8,4 @@ brace to mark the end of the message.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -9,4 +9,4 @@ braces.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -10,4 +10,4 @@ extensions require that you provide a message for the selection "other".
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
@@ -9,4 +9,4 @@ unsupported or invalid.
For more information about the MessageFormat syntax in interpolation
expressions, please refer to MessageFormat extensions section at
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
{@link guide/i18n#MessageFormat AngularJS i18n MessageFormat}
+1 -1
View File
@@ -7,4 +7,4 @@ You have attempted to use a MessageFormat extension in your interpolation expres
Read more about secure contexts at {@link ng.$sce Strict Contextual Escaping
(SCE)} and about the MessageFormat extensions at {@link
guide/i18n#MessageFormat Angular i18n MessageFormat}.
guide/i18n#MessageFormat AngularJS i18n MessageFormat}.
@@ -3,4 +3,4 @@
@fullName Unterminated string literal
@description
The string literal was not terminated in your Angular expression.
The string literal was not terminated in your AngularJS expression.
+1 -1
View File
@@ -40,7 +40,7 @@ URL of the subcontext:
</head>
```
Before Angular 1.3 we didn't have this hard requirement and it was easy to write apps that worked
Before AngularJS 1.3 we didn't have this hard requirement and it was easy to write apps that worked
when deployed in the root context but were broken when moved to a sub-context because in the
sub-context all absolute urls would resolve to the root context of the app. To prevent this,
use relative URLs throughout your app:
+10
View File
@@ -0,0 +1,10 @@
@ngdoc error
@name $parse:esc
@fullName Value cannot be escaped
@description
Occurs when the parser tries to escape a value that is not known.
This should never occur in practice. If it does then that indicates a programming
error in the AngularJS `$parse` service itself and should be reported as an issue
at https://github.com/angular/angular.js/issues.
+1 -1
View File
@@ -7,4 +7,4 @@ Occurs when an expression has a lexical error, for example a malformed number (0
The error message contains a more precise error.
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and fix the expression's syntax.
To resolve, learn more about {@link guide/expression AngularJS expressions}, identify the error and fix the expression's syntax.
+13
View File
@@ -0,0 +1,13 @@
@ngdoc error
@name $parse:lval
@fullName Trying to assign a value to a non l-value
@description
Occurs when an expression is trying to assign a value to a non-assignable expression.
This can happen if the left side of an assigment is not a valid reference to a variable
or property. E.g. In the following snippet `1+2` is not assignable.
```
(1+2) = 'hello';
```
+1 -1
View File
@@ -6,4 +6,4 @@
Occurs when there is a syntax error in an expression. These errors are thrown while compiling the expression.
The error message contains a more precise description of the error, including the location (column) in the expression where the error occurred.
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and fix the expression's syntax.
To resolve, learn more about {@link guide/expression AngularJS expressions}, identify the error and fix the expression's syntax.
+1 -1
View File
@@ -8,5 +8,5 @@ Occurs when an expression is missing tokens at the end of the expression.
For example, forgetting to close a bracket or failing to properly escape quotes in an expression
will trigger this error.
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and
To resolve, learn more about {@link guide/expression AngularJS expressions}, identify the error and
fix the expression's syntax.
+2 -2
View File
@@ -4,7 +4,7 @@
@description
This error occurs when the application's model becomes unstable and each `$digest` cycle triggers a state change and subsequent `$digest` cycle.
Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
For example, the situation can occur by setting up a watch on a path and subsequently updating the same path when the value changes.
@@ -26,7 +26,7 @@ $scope.getUsers = function() {
};
```
Since `getUsers()` returns a new array, Angular determines that the model is different on each `$digest`
Since `getUsers()` returns a new array, AngularJS determines that the model is different on each `$digest`
cycle, resulting in the error. The solution is to return the same array object if the elements have
not changed:
+16 -16
View File
@@ -10,17 +10,17 @@ the error.
## Background
Angular uses a dirty-checking digest mechanism to monitor and update values of the scope during
AngularJS uses a dirty-checking digest mechanism to monitor and update values of the scope during
the processing of your application. The digest works by checking all the values that are being
watched against their previous value and running any watch handlers that have been defined for those
values that have changed.
This digest mechanism is triggered by calling `$digest` on a scope object. Normally you do not need
to trigger a digest manually, because every external action that can trigger changes in your
application, such as mouse events, timeouts or server responses, wrap the Angular application code
application, such as mouse events, timeouts or server responses, wrap the AngularJS application code
in a block of code that will run `$digest` when the code completes.
You wrap Angular code in a block that will be followed by a `$digest` by calling `$apply` on a scope
You wrap AngularJS code in a block that will be followed by a `$digest` by calling `$apply` on a scope
object. So, in pseudo-code, the process looks like this:
```
@@ -45,20 +45,20 @@ $apply = function(fn) {
## Digest Phases
Angular keeps track of what phase of processing we are in, the relevant ones being `$apply` and
AngularJS keeps track of what phase of processing we are in, the relevant ones being `$apply` and
`$digest`. Trying to reenter a `$digest` or `$apply` while one of them is already in progress is
typically a sign of programming error that needs to be fixed. So Angular will throw this error when
typically a sign of programming error that needs to be fixed. So AngularJS will throw this error when
that occurs.
In most situations it should be well defined whether a piece of code will be run inside an `$apply`,
in which case you should not be calling `$apply` or `$digest`, or it will be run outside, in which
case you should wrap any code that will be interacting with Angular scope or services, in a call to
case you should wrap any code that will be interacting with AngularJS scope or services, in a call to
`$apply`.
As an example, all Controller code should expect to be run within Angular, so it should have no need
As an example, all Controller code should expect to be run within AngularJS, so it should have no need
to call `$apply` or `$digest`. Conversely, code that is being trigger directly as a call back to
some external event, from the DOM or 3rd party library, should expect that it is never called from
within Angular, and so any Angular application code that it calls should first be wrapped in a call
within AngularJS, and so any AngularJS application code that it calls should first be wrapped in a call
to $apply.
## Common Causes
@@ -84,8 +84,8 @@ function MyController($scope, thirdPartyComponent) {
}
```
We expect that our callback will be called asynchronously, and so from outside Angular. Therefore, we
correctly wrap our application code that interacts with Angular in a call to `$apply`.
We expect that our callback will be called asynchronously, and so from outside AngularJS. Therefore, we
correctly wrap our application code that interacts with AngularJS in a call to `$apply`.
The problem comes if `getData()` decides to call the callback handler synchronously; perhaps it has
the data already cached in memory and so it immediately calls the callback to return the data,
@@ -116,7 +116,7 @@ that the code will be called in a single `$apply` block.
### Triggering Events Programmatically
The other situation that often leads to this error is when you trigger code (such as a DOM event)
programmatically (from within Angular), which is normally called by an external trigger.
programmatically (from within AngularJS), which is normally called by an external trigger.
For example, consider a directive that will set focus on an input control when a value in the scope
is true:
@@ -161,7 +161,7 @@ In this second scenario, we are already inside a `$digest` when the ngFocus dire
call to `$apply()`, causing this error to be thrown.
It is possible to workaround this problem by moving the call to set the focus outside of the digest,
by using `$timeout(fn, 0, false)`, where the `false` value tells Angular not to wrap this `fn` in an
by using `$timeout(fn, 0, false)`, where the `false` value tells AngularJS not to wrap this `fn` in an
`$apply` block:
```
@@ -203,7 +203,7 @@ Once you have identified this call you work your way up the stack to see what th
called from within an `$apply`/`$digest`. It may be a simple oversight or maybe it fits with the
sync/async scenario described earlier.
* If the second call was made inside an Angular directive then it is likely that it matches the second
* If the second call was made inside an AngularJS directive then it is likely that it matches the second
programmatic event trigger scenario described earlier. In this case you may need to look further up
the tree to what triggered the event in the first place.
@@ -259,11 +259,11 @@ $get.g.$apply angular.js:12742 <--- $apply
q angular.js:320
```
We can see (even though the Angular code is minified) that there were two calls to `$apply`, first
We can see (even though the AngularJS code is minified) that there were two calls to `$apply`, first
on line `19833`, then on line `12738` of `angular.js`.
It is this second call that caused the error. If we look at the angular.js code, we can see that
this call is made by an Angular directive.
this call is made by an AngularJS directive.
```
var ngEventDirectives = {};
@@ -308,5 +308,5 @@ We can now see that the second `$apply` was caused by us programmatically trigge
`$timeout` as described above.
## Further Reading
To learn more about Angular processing model please check out the
To learn more about AngularJS processing model please check out the
{@link guide/concepts concepts doc} as well as the {@link ng.$rootScope.Scope api} doc.
+8
View File
@@ -0,0 +1,8 @@
@ngdoc error
@name $route:norout
@fullName Tried updating route with no current route
@description
Occurs when an attempt is made to update the parameters on the current route when
there is no current route. This can happen if you try to call `$route.updateParams();`
before the first route transition has completed.
+1 -1
View File
@@ -7,4 +7,4 @@ This error occurs when `$sanitize` sanitizer determines that `document.implement
This api is necessary for safe parsing of HTML strings into DOM trees and without it the sanitizer can't sanitize the input.
The api is present in all supported browsers including IE 9.0, so the presence of this error usually indicates that Angular's `$sanitize` is being used on an unsupported platform.
The api is present in all supported browsers including IE 9.0, so the presence of this error usually indicates that AngularJS's `$sanitize` is being used on an unsupported platform.
+2 -2
View File
@@ -5,10 +5,10 @@
AngularJS' {@link ng.$sce Strict Contextual Escaping (SCE)} mode (enabled by default) has blocked loading a resource from an insecure URL.
Typically, this would occur if you're attempting to load an Angular template from an untrusted source.
Typically, this would occur if you're attempting to load an AngularJS template from an untrusted source.
It's also possible that a custom directive threw this error for a similar reason.
Angular only loads templates from trusted URLs (by calling {@link ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl} on the template URL).
AngularJS only loads templates from trusted URLs (by calling {@link ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl} on the template URL).
By default, only URLs that belong to the same origin are trusted. These are urls with the same domain, protocol and port as the application document.
+2 -2
View File
@@ -5,10 +5,10 @@
The value provided for use in a specific context was not found to be safe/trusted for use.
Angular's {@link ng.$sce Strict Contextual Escaping (SCE)} mode
AngularJS's {@link ng.$sce Strict Contextual Escaping (SCE)} mode
(enabled by default), requires bindings in certain
contexts to result in a value that is trusted as safe for use in such a context. (e.g. loading an
Angular template from a URL requires that the URL is one considered safe for loading resources.)
AngularJS template from a URL requires that the URL is one considered safe for loading resources.)
This helps prevent XSS and other security issues. Read more at
{@link ng.$sce Strict Contextual Escaping (SCE)}
+6 -3
View File
@@ -3,9 +3,12 @@
@fullName Unsupported Selector Lookup
@description
In order to keep Angular small, Angular implements only a subset of the selectors in {@link angular.element#angular-s-jqlite jqLite}.
In order to keep AngularJS small, AngularJS implements only a subset of the selectors in
{@link angular.element#angularjs-s-jqlite jqLite}.
This error occurs when a jqLite instance is invoked with a selector other than this subset.
In order to resolve this error, rewrite your code to only use tag name selectors and manually traverse the DOM using the APIs provided by jqLite.
In order to resolve this error, rewrite your code to only use tag name selectors and manually
traverse the DOM using the APIs provided by jqLite.
Alternatively, you can include a full version of jQuery, which Angular will automatically use and that will make all selectors available.
Alternatively, you can include a full version of jQuery, which AngularJS will automatically use
and that will make all selectors available.
+2 -2
View File
@@ -3,7 +3,7 @@
@fullName Testability Not Found
@description
Angular's testability helper, getTestability, requires a root element to be
passed in. This helps differentiate between different Angular apps on the same
AngularJS's testability helper, getTestability, requires a root element to be
passed in. This helps differentiate between different AngularJS apps on the same
page. This error is thrown when no injector is found for root element. It is
often because the root element is outside of the ng-app.
+1 -1
View File
@@ -5,7 +5,7 @@
All date-related inputs like `<input type="date">` require the model to be a `Date` object.
If the model is something else, this error will be thrown.
Angular does not set validation errors on the `<input>` in this case
AngularJS does not set validation errors on the `<input>` in this case
as those errors are shown to the user, but the erroneous state was
caused by incorrect application logic and not by the user.
+1 -1
View File
@@ -7,7 +7,7 @@ The `input[number]` and `input[range]` directives require the model to be a `num
If the model is something else, this error will be thrown.
Angular does not set validation errors on the `<input>` in this case
AngularJS does not set validation errors on the `<input>` in this case
as this error is caused by incorrect application logic and not by bad input from the user.
If your model does not contain actual numbers then it is up to the application developer
+9 -9
View File
@@ -48,7 +48,7 @@ changes to `$location` are reflected into the browser address bar.
</tr>
<tr>
<td class="head">integration with angular application life-cycle</td>
<td class="head">integration with AngularJS application life-cycle</td>
<td>none</td>
<td>knows about all internal life-cycle phases, integrates with {@link ng.$rootScope.Scope#$watch $watch}, ...</td>
</tr>
@@ -224,7 +224,7 @@ facilitate the browser URL change and history management.
## Hashbang mode (default mode)
In this mode, `$location` uses Hashbang URLs in all browsers.
Angular also does not intercept and rewrite links in this mode. I.e. links work
AngularJS also does not intercept and rewrite links in this mode. I.e. links work
as expected and also perform full page reloads when other parts of the url
than the hash fragment was changed.
@@ -267,7 +267,7 @@ having to worry about whether the browser displaying your app supports the histo
- Opening a regular URL in a legacy browser -> redirects to a hashbang URL
- Opening hashbang URL in a modern browser -> rewrites to a regular URL
Note that in this mode, Angular intercepts all links (subject to the "Html link rewriting" rules below)
Note that in this mode, AngularJS intercepts all links (subject to the "Html link rewriting" rules below)
and updates the url in a way that never performs a full page reload.
@@ -363,7 +363,7 @@ Note that [attribute name normalization](guide/directive#normalization) does not
### Relative links
Be sure to check all relative links, images, scripts etc. Angular requires you to specify the url
Be sure to check all relative links, images, scripts etc. AngularJS requires you to specify the url
base in the head of your main html file (`<base href="/my-base/index.html">`) unless `html5Mode.requireBase`
is set to `false` in the html5Mode definition object passed to `$locationProvider.html5Mode()`. With
that, relative urls will always be resolved to this base url, even if the initial url of the
@@ -378,7 +378,7 @@ to anchors on the same page without needing to know on which page the user curre
Using this mode requires URL rewriting on server side, basically you have to rewrite all your links
to entry point of your application (e.g. index.html). Requiring a `<base>` tag is also important for
this case, as it allows Angular to differentiate between the part of the url that is the application
this case, as it allows AngularJS to differentiate between the part of the url that is the application
base and the path that should be handled by the application.
### Base href constraints
@@ -391,7 +391,7 @@ called `/base`). The URL `/base` is actually outside the application (it refers
in the root `/` folder).
If you wish to be able to navigate to the application via a URL such as `/base` then you should ensure that
you server is setup to redirect such requests to `/base/`.
your server is setup to redirect such requests to `/base/`.
See https://github.com/angular/angular.js/issues/14018 for more information.
@@ -728,14 +728,14 @@ use a lower level API, {@link ng.$window $window.location.href}.
## Using $location outside of the scope life-cycle
`$location` knows about Angular's {@link ng.$rootScope.Scope scope} life-cycle. When a URL changes in
`$location` knows about AngularJS's {@link ng.$rootScope.Scope scope} life-cycle. When a URL changes in
the browser it updates the `$location` and calls `$apply` so that all
{@link ng.$rootScope.Scope#$watch $watchers} /
{@link ng.$compile.directive.Attributes#$observe $observers} are notified.
When you change the `$location` inside the `$digest` phase everything is ok; `$location` will
propagate this change into browser and will notify all the {@link ng.$rootScope.Scope#$watch $watchers} /
{@link ng.$compile.directive.Attributes#$observe $observers}.
When you want to change the `$location` from outside Angular (for example, through a DOM Event or
When you want to change the `$location` from outside AngularJS (for example, through a DOM Event or
during testing) - you must call `$apply` to propagate the changes.
## $location.path() and ! or / prefixes
@@ -787,7 +787,7 @@ describe('serviceUnderTest', function() {
# Migrating from earlier AngularJS releases
In earlier releases of Angular, `$location` used `hashPath` or `hashSearch` to process path and
In earlier releases of AngularJS, `$location` used `hashPath` or `hashSearch` to process path and
search methods. With this release, the `$location` service processes path and search methods and
then uses the information it obtains to compose hashbang URLs (such as
`http://server.com/#!/path?search=a`), when necessary.
+4 -4
View File
@@ -6,7 +6,7 @@
# Accessibility with ngAria
The goal of ngAria is to improve Angular's default accessibility by enabling common
The goal of ngAria is to improve AngularJS's default accessibility by enabling common
[ARIA](http://www.w3.org/TR/wai-aria/) attributes that convey state or semantic information for
assistive technologies used by persons with disabilities.
@@ -109,11 +109,11 @@ attributes (if they have not been explicitly specified by the developer):
function isEmpty(value) {
return !value;
}
function render() {
elem[ctrl.$viewValue ? 'addClass' : 'removeClass']('checked');
}
function toggleCheckbox() {
ctrl.$setViewValue(!ctrl.$viewValue);
ctrl.$render();
@@ -420,7 +420,7 @@ tell ngAria to ignore the attribute globally.
## Common Accessibility Patterns
Accessibility best practices that apply to web apps in general also apply to Angular.
Accessibility best practices that apply to web apps in general also apply to AngularJS.
* **Text alternatives**: Add alternate text content to make visual information accessible using
[these W3C guidelines](http://www.w3.org/TR/html-alt-techniques/). The appropriate technique
+6 -5
View File
@@ -66,7 +66,7 @@ You may also want to setup a separate CSS file for defining CSS-based animations
## How they work
Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class
attached to a HTML element within your application, you can apply animations to it. Lets say for
attached to an HTML element within your application, you can apply animations to it. Let's say for
example that we have an HTML template with a repeater like so:
```html
@@ -229,11 +229,12 @@ triggered:
| {@link ngRoute.directive:ngView#animations ngView} | enter and leave |
| {@link module:ngMessages#animations ngMessage / ngMessageExp} | enter and leave |
| {@link ng.directive:ngClass#animations ngClass / {{class&#125;&#8203;&#125;} | add and remove |
| {@link ng.directive:ngClass#animations ngClassEven / ngClassOdd} | add and remove |
| {@link ng.directive:ngClassEven#animations ngClassEven} | add and remove |
| {@link ng.directive:ngClassOdd#animations ngClassOdd} | add and remove |
| {@link ng.directive:ngHide#animations ngHide} | add and remove (the `ng-hide` class) |
| {@link ng.directive:ngShow#animations ngShow} | add and remove (the `ng-hide` class) |
| {@link ng.directive:ngModel#animations ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) |
| {@link ng.directive:form#animations form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) |
| {@link ng.directive:ngModel#animations ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) |
| {@link ng.directive:form#animations form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) |
| {@link module:ngMessages#animations ngMessages} | add and remove (the `ng-active`/`ng-inactive` classes) |
For a full breakdown of the steps involved during each animation event, refer to the
@@ -467,7 +468,7 @@ You can also use one of the other
strategies to disable animations}.
## Enable animations outside of the application DOM tree: {@link ng.$animate#pin $animate.pin()}
### Enable animations for elements outside of the AngularJS application DOM tree: {@link ng.$animate#pin $animate.pin()}
Before animating, `ngAnimate` checks if the animated element is inside the application DOM tree. If
not, no animation is run. Usually, this is not a problem since most apps use the `html` or `body`
+10 -10
View File
@@ -5,13 +5,13 @@
# Bootstrap
This page explains the Angular initialization process and how you can manually initialize Angular
This page explains the AngularJS initialization process and how you can manually initialize AngularJS
if necessary.
## Angular `<script>` Tag
## AngularJS `<script>` Tag
This example shows the recommended path for integrating Angular with what we call automatic
This example shows the recommended path for integrating AngularJS with what we call automatic
initialization.
@@ -35,7 +35,7 @@ initialization.
* Choose: `angular-[version].min.js` for a compressed and obfuscated file, suitable for use in
production.
2. Place `ng-app` to the root of your application, typically on the `<html>` tag if you want
angular to auto-bootstrap your application.
AngularJS to auto-bootstrap your application.
<html ng-app>
@@ -51,16 +51,16 @@ initialization.
<img class="pull-right" style="padding-left: 3em;" src="img/guide/concepts-startup.png">
Angular initializes automatically upon `DOMContentLoaded` event or when the `angular.js` script is
evaluated if at that time `document.readyState` is set to `'complete'`. At this point Angular looks
AngularJS initializes automatically upon `DOMContentLoaded` event or when the `angular.js` script is
evaluated if at that time `document.readyState` is set to `'complete'`. At this point AngularJS looks
for the {@link ng.directive:ngApp `ngApp`} directive which designates your application root.
If the {@link ng.directive:ngApp `ngApp`} directive is found then Angular will:
If the {@link ng.directive:ngApp `ngApp`} directive is found then AngularJS will:
* load the {@link guide/module module} associated with the directive.
* create the application {@link auto.$injector injector}
* compile the DOM treating the {@link ng.directive:ngApp
`ngApp`} directive as the root of the compilation. This allows you to tell it to treat only a
portion of the DOM as an Angular application.
portion of the DOM as an AngularJS application.
```html
@@ -96,9 +96,9 @@ for more.
If you need to have more control over the initialization process, you can use a manual
bootstrapping method instead. Examples of when you'd need to do this include using script loaders
or the need to perform an operation before Angular compiles a page.
or the need to perform an operation before AngularJS compiles a page.
Here is an example of manually initializing Angular:
Here is an example of manually initializing AngularJS:
```html
<!doctype html>
+10 -10
View File
@@ -10,15 +10,15 @@
If you're just getting started, we recommend the {@link tutorial/ tutorial} first.
If you just want to create custom directives, we recommend the {@link guide/directive directives guide}.
If you want a deeper look into Angular's compilation process, you're in the right place.
If you want a deeper look into AngularJS's compilation process, you're in the right place.
</div>
## Overview
Angular's {@link ng.$compile HTML compiler} allows the developer to teach the
AngularJS's {@link ng.$compile HTML compiler} allows the developer to teach the
browser new HTML syntax. The compiler allows you to attach behavior to any HTML element or attribute
and even create new HTML elements or attributes with custom behavior. Angular calls these behavior
and even create new HTML elements or attributes with custom behavior. AngularJS calls these behavior
extensions {@link ng.$compileProvider#directive directives}.
HTML has a lot of constructs for formatting the HTML for static documents in a declarative fashion.
@@ -31,7 +31,7 @@ However, the declarative language is also limited, as it does not allow you to t
syntax. For example, there is no easy way to get the browser to align the text at 1/3 the position
instead of 1/2. What is needed is a way to teach the browser new HTML syntax.
Angular comes pre-bundled with common directives which are useful for building any app. We also
AngularJS comes pre-bundled with common directives which are useful for building any app. We also
expect that you will create directives that are specific to your app. These extensions become a
Domain Specific Language for building your application.
@@ -41,7 +41,7 @@ involved.
## Compiler
Compiler is an Angular service which traverses the DOM looking for attributes. The compilation
Compiler is an AngularJS service which traverses the DOM looking for attributes. The compilation
process happens in two phases.
1. **Compile:** traverse the DOM and collect all of the directives. The result is a linking
@@ -142,16 +142,16 @@ This means that any changes to the data need to be re-merged with the template a
3. managing the whole update process
4. lack of behavior expressiveness
Angular is different. The Angular compiler consumes the DOM, not string templates.
AngularJS is different. The AngularJS compiler consumes the DOM, not string templates.
The result is a linking function, which when combined with a scope model results in a live view. The
view and scope model bindings are transparent. The developer does not need to make any special calls to update
the view. And because `innerHTML` is not used, you won't accidentally clobber user input.
Furthermore, Angular directives can contain not just text bindings, but behavioral constructs as
Furthermore, AngularJS directives can contain not just text bindings, but behavioral constructs as
well.
<img src="img/Two_Way_Data_Binding.png">
The Angular approach produces a stable DOM. The DOM element instance bound to a model
The AngularJS approach produces a stable DOM. The DOM element instance bound to a model
item instance does not change for the lifetime of the binding. This means that the code can get
hold of the elements and register event handlers and know that the reference will not be destroyed
by template data merge.
@@ -160,7 +160,7 @@ by template data merge.
## How directives are compiled
It's important to note that Angular operates on DOM nodes rather than strings. Usually, you don't
It's important to note that AngularJS operates on DOM nodes rather than strings. Usually, you don't
notice this restriction because when a page loads, the web browser parses HTML into the DOM automatically.
HTML compilation happens in three phases:
@@ -186,7 +186,7 @@ The result of this is a live binding between the scope and the DOM. So at this p
a model on the compiled scope will be reflected in the DOM.
Below is the corresponding code using the `$compile` service.
This should help give you an idea of what Angular does internally.
This should help give you an idea of what AngularJS does internally.
```js
var $compile = ...; // injected into your code
+34 -35
View File
@@ -10,11 +10,10 @@
We are investigating backporting the new Angular Router to AngularJS, but alternatively, use the {@link ngRoute} module or community developed projects (e.g. [ui-router](https://github.com/angular-ui/ui-router)).
</div>
This guide describes the new Component Router for AngularJS 1.5.
This guide describes the Component Router for AngularJS.
<div class="alert alert-info">
If you are looking for information about the default router for AngularJS have a look at the {@link ngRoute} module.
If you are looking for information about the Component Router for the new Angular then
check out the [Angular Router Guide](https://angular.io/docs/ts/latest/guide/router.html).
</div>
@@ -28,7 +27,7 @@ Here is a table of the main concepts used in the Component Router.
| Router | Displays the Routing Components for the active Route. Manages navigation from one component to the next. |
| RootRouter | The top level Router that interacts with the current URL location |
| RouteConfig | Configures a Router with RouteDefinitions, each mapping a URL path to a component. |
| Routing Component | An Angular component with a RouteConfig and an associated Router. |
| Routing Component | An AngularJS component with a RouteConfig and an associated Router. |
| RouteDefinition | Defines how the router should navigate to a component based on a URL pattern. |
| ngOutlet | The directive (`<ng-outlet>`) that marks where the router should display a view. |
| ngLink | The directive (`ng-link="..."`) for binding a clickable HTML element to a route, via a Link Parameters Array. |
@@ -138,7 +137,7 @@ The result is that we end up with a hierarchy of **Routing Components** rendered
![Component Hierarchy](img/guide/component-hierarchy.svg)
# Example Heroes App
## Example Heroes App
You can see the complete application running below.
@@ -459,12 +458,12 @@ You can see the complete application running below.
</example>
# Getting Started
### Getting Started
In the following sections we will step through building this application. The finished application has views
to display list and detail views of Heroes and Crises.
## Install the libraries
#### Install the libraries
It is easier to use [Yarn](https://yarnpkg.com) or [npm](https://www.npmjs.com) to install the
**Component Router** module. For this guide we will also install AngularJS itself via Yarn:
@@ -475,9 +474,9 @@ yarn add angular@1.5.x @angular/router@0.2.0
```
## Load the scripts
#### Load the scripts
Just like any Angular application, we load the JavaScript files into our `index.html`:
Just like any AngularJS application, we load the JavaScript files into our `index.html`:
```html
<script src="/node_modules/angular/angular.js"></script>
@@ -494,7 +493,7 @@ You also need to include ES6 shims for browsers that do not support ES6 code (In
<script src="https://unpkg.com/angular2/es6/dev/src/testing/shims_for_IE.js"></script>
```
## Create the `app` module
#### Create the `app` module
In the app.js file, create the main application module `app` which depends on the `ngComponentRouter`
module, which is provided by the **Component Router** script.
@@ -528,7 +527,7 @@ Configure the top level routed `App` Component.
Create a very simple App Component to test that the application is working.
We are using the Angular 1.5 {@link $compileProvider#component `.component()`} helper method to create
We are using the AngularJS {@link $compileProvider#component `.component()`} helper method to create
all the **Components** in our application. It is perfectly suited to this task.
```js
@@ -547,9 +546,9 @@ must have a base URL.
...
```
## Bootstrap AngularJS
#### Bootstrap AngularJS
Bootstrap the Angular application and add the top level App Component.
Bootstrap the AngularJS application and add the top level App Component.
```html
<body ng-app="app">
@@ -559,7 +558,7 @@ Bootstrap the Angular application and add the top level App Component.
```
# Implementing the AppComponent
### Implementing the AppComponent
In the previous section we have created a single top level **App Component**. Let's now create some more
**Routing Components** and wire up **Route Config** for those. We start with a Heroes Feature, which
@@ -577,7 +576,7 @@ We are going to have a `Heroes` Component for the Heroes feature of our applicat
and `HeroDetail` **Components** that will actually display the two different views.
## App Component
#### App Component
Configure the **App Component** with a template and **Route Config**:
@@ -598,7 +597,7 @@ Configure the **App Component** with a template and **Route Config**:
The **App Component** has an `<ng-outlet>` directive in its template. This is where the child **Components**
of this view will be rendered.
### ngLink
#### ngLink
We have used the `ng-link` directive to create a link to navigate to the Heroes Component. By using this
directive we don't need to know what the actual URL will be. We can let the Router generate that for us.
@@ -607,7 +606,7 @@ We have included a link to the Crisis Center but have not included the `ng-link`
implemented the CrisisCenter component.
### Non-terminal Routes
#### Non-terminal Routes
We need to tell the **Router** that the `Heroes` **Route Definition** is **non-terminal**, that it should
continue to match **Routes** in its child **Components**. We do this by adding a **continuation ellipsis
@@ -616,16 +615,16 @@ Without the **continuation ellipsis** the `HeroList` **Route** will never be mat
stop at the `Heroes` **Routing Component** and not try to match the rest of the URL.
## Heroes Feature
### Heroes Feature
Now we can implement our Heroes Feature which consists of three **Components**: `Heroes`, `HeroList` and
`HeroDetail`. The `Heroes` **Routing Component** simply provides a template containing the {@link ngOutlet}
directive and a **Route Config** that defines a set of child **Routes** which delegate through to the
`HeroList` and `HeroDetail` **Components**.
## HeroesComponent
### HeroesComponent
Create a new file `heroes.js`, which defines a new Angular module for the **Components** of this feature
Create a new file `heroes.js`, which defines a new AngularJS module for the **Components** of this feature
and registers the Heroes **Component**.
```js
@@ -651,20 +650,20 @@ and also to add the module as a dependency of the `app` module:
angular.module('app', ['ngComponentRouter', 'heroes'])
```
### Use As Default
#### Use As Default
The `useAsDefault` property on the `HeroList` **Route Definition**, indicates that if no other **Route
Definition** matches the URL, then this **Route Definition** should be used by default.
### Route Parameters
#### Route Parameters
The `HeroDetail` Route has a named parameter (`id`), indicated by prefixing the URL segment with a colon,
as part of its `path` property. The **Router** will match anything in this segment and make that value
available to the HeroDetail **Component**.
### Terminal Routes
#### Terminal Routes
Both the Routes in the `HeroesComponent` are terminal, i.e. their routes do not end with `...`. This is
because the `HeroList` and `HeroDetail` will not contain any child routes.
### Route Names
#### Route Names
**What is the difference between the `name` and `component` properties on a Route Definition?**
The `component` property in a **Route Definition** defines the **Component** directive that will be rendered
@@ -676,7 +675,7 @@ The `name` property is used to reference the **Route Definition** when generatin
that has the `name` property of `"Heroes"`.
## HeroList Component
### HeroList Component
The HeroList **Component** is the first component in the application that actually contains significant
functionality. It loads up a list of heroes from a `heroService` and displays them using `ng-repeat`.
@@ -705,7 +704,7 @@ The template iterates through each `hero` object of the array in the `$ctrl.hero
the `$ctrl` property on the scope of the template.*
## HeroService
### HeroService
Our HeroService simulates requesting a list of heroes from a server. In a real application this would be
making an actual server request, perhaps over HTTP.
@@ -735,7 +734,7 @@ Note that both the `getHeroes()` and `getHero(id)` methods return a promise for
in real-life we would have to wait for the server to respond with the data.
## Router Lifecycle Hooks
### Router Lifecycle Hooks
**How do I know when my Component is active?**
@@ -780,7 +779,7 @@ By returning a promise for the list of heroes from `$routerOnActivate()` we can
Route until the heroes have arrived successfully. This is similar to how a `resolve` works in {@link ngRoute}.
## Route Parameters
### Route Parameters
**How do I access parameters for the current route?**
@@ -811,11 +810,11 @@ by the **Router**. In this code it is used to identify a specific Hero to retrie
This hero is then attached to the **Component** so that it can be accessed in the template.
## Access to the Current Router
### Access to the Current Router
**How do I get hold of the current router for my component?**
Each component has its own Router. Unlike in Angular 2, we cannot use the dependency injector to get hold of a component's Router.
Each component has its own Router. Unlike in the new Angular, we cannot use the dependency injector to get hold of a component's Router.
We can only inject the `$rootRouter`. Instead we use the fact that the `ng-outlet` directive binds the current router to a `$router`
attribute on our component.
@@ -882,7 +881,7 @@ Other options for generating this navigation are:
```
this form gives you the possibility of caching the instruction, but is more verbose.
### Absolute vs Relative Navigation
#### Absolute vs Relative Navigation
**Why not use `$rootRouter` to do the navigation?**
@@ -894,7 +893,7 @@ to the `HeroListComponent` with the `$rootRouter`, we would have to provide a co
`['App','Heroes','HeroList']`.
## Extra Parameters
### Extra Parameters
We can also pass additional optional parameters to routes, which get encoded into the URL and are again
available to the `$routerOnActivate(next, previous)` hook. If we pass the current `id` from the
@@ -936,7 +935,7 @@ Finally, we can use this information to highlight the current hero in the templa
</div>
```
## Crisis Center
### Crisis Center
Let's implement the Crisis Center feature, which displays a list if crises that need to be dealt with by a hero.
The detailed crisis view has an additional feature where it blocks you from navigating if you have not saved
@@ -951,7 +950,7 @@ changes to the crisis being edited.
![Crisis Detail View](img/guide/crisis-detail.png)
## Crisis Feature
### Crisis Feature
This feature is very similar to the Heroes feature. It contains the following **Components**:
@@ -962,7 +961,7 @@ This feature is very similar to the Heroes feature. It contains the following **
CrisisService and CrisisListComponent are basically the same as HeroService and HeroListComponent
respectively.
## Navigation Control Hooks
### Navigation Control Hooks
**How do I prevent navigation from occurring?**
@@ -979,7 +978,7 @@ can complete, all the **Components** must agree that they can be deactivated or
The **Router** will call the `$routerCanDeactivate` and `$canActivate` hooks, if they are provided. If any
of the hooks resolve to `false` then the navigation is cancelled.
### Dialog Box Service
#### Dialog Box Service
We can implement a very simple dialog box that will prompt the user whether they are happy to lose changes they
have made. The result of the prompt is a promise that can be used in a `$routerCanDeactivate` hook.
+11 -11
View File
@@ -5,17 +5,17 @@
# Understanding Components
In Angular, a Component is a special kind of {@link guide/directive directive} that uses a simpler
In AngularJS, a Component is a special kind of {@link guide/directive directive} that uses a simpler
configuration which is suitable for a component-based application structure.
This makes it easier to write an app in a way that's similar to using Web Components or using Angular
2's style of application architecture.
This makes it easier to write an app in a way that's similar to using Web Components or using the new Angular's
style of application architecture.
Advantages of Components:
- simpler configuration than plain directives
- promote sane defaults and best practices
- optimized for component-based architecture
- writing component directives will make it easier to upgrade to Angular 2
- writing component directives will make it easier to upgrade to Angular
When not to use Components:
@@ -25,7 +25,7 @@ When not to use Components:
## Creating and configuring a Component
Components can be registered using the `.component()` method of an Angular module (returned by {@link module `angular.module()`}). The method takes two arguments:
Components can be registered using the `.component()` method of an AngularJS module (returned by {@link module `angular.module()`}). The method takes two arguments:
* The name of the Component (as string).
* The Component config object. (Note that, unlike the `.directive()` method, this method does **not** take a factory function.)
@@ -90,14 +90,14 @@ a component-based architecture. But what makes a component beyond the options th
the component helper has?
- **Components only control their own View and Data:**
Components should never modify any data or DOM that is out of their own scope. Normally, in Angular
Components should never modify any data or DOM that is out of their own scope. Normally, in AngularJS
it is possible to modify data anywhere in the application through scope inheritance and watches. This
is practical, but can also lead to problems when it is not clear which part of the application is
responsible for modifying the data. That is why component directives use an isolate scope, so a whole
class of scope manipulation is not possible.
- **Components have a well-defined public API - Inputs and Outputs:**
However, scope isolation only goes so far, because Angular uses two-way binding. So if you pass
However, scope isolation only goes so far, because AngularJS uses two-way binding. So if you pass
an object to a component like this - `bindings: {item: '='}`, and modify one of its properties, the
change will be reflected in the parent component. For components however, only the component that owns
the data should modify it, to make it easy to reason about what data is changed, and when. For that reason,
@@ -158,7 +158,7 @@ of the component. The following hook methods can be implemented:
changes. Any actions that you wish to take in response to the changes that you detect must be
invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook
could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not
be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
be detected by AngularJS's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
if detecting changes, you must store the previous value(s) for comparison to the current values.
* `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
external resources, watches and event handlers.
@@ -167,8 +167,8 @@ of the component. The following hook methods can be implemented:
Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
they are waiting for their template to load asynchronously and their own compilation and linking has been
suspended until that occurs.
This hook can be considered analogous to the `ngAfterViewInit` and `ngAfterContentInit` hooks in Angular 2.
Since the compilation process is rather different in Angular 1 there is no direct mapping and care should
This hook can be considered analogous to the `ngAfterViewInit` and `ngAfterContentInit` hooks in Angular.
Since the compilation process is rather different in AngularJS there is no direct mapping and care should
be taken when upgrading.
By implementing these methods, your component can hook into its lifecycle.
@@ -445,7 +445,7 @@ angular.module('docsTabsExample', [])
</example>
# Unit-testing Component Controllers
## Unit-testing Component Controllers
The easiest way to unit-test a component controller is by using the
{@link ngMock.$componentController $componentController} that is included in {@link ngMock}. The
+22 -22
View File
@@ -54,20 +54,20 @@ Try out the Live Preview above, and then let's walk through the example and desc
<img class="pull-right" style="padding-left: 3em; padding-bottom: 1em;" src="img/guide/concepts-databinding1.png">
This looks like normal HTML, with some new markup. In Angular, a file like this is called a
<a name="template">{@link templates template}</a>. When Angular starts your application, it parses and
This looks like normal HTML, with some new markup. In AngularJS, a file like this is called a
<a name="template">{@link templates template}</a>. When AngularJS starts your application, it parses and
processes this new markup from the template using the <a name="compiler">{@link compiler compiler}</a>.
The loaded, transformed and rendered DOM is then called the <a name="view"></a>*view*.
The first kind of new markup are the <a name="directive">{@link directive directives}</a>.
They apply special behavior to attributes or elements in the HTML. In the example above we use the
{@link ng.directive:ngApp `ng-app`} attribute, which is linked to a directive that automatically
initializes our application. Angular also defines a directive for the {@link ng.directive:input `input`}
initializes our application. AngularJS also defines a directive for the {@link ng.directive:input `input`}
element that adds extra behavior to the element. The {@link ng.directive:ngModel `ng-model`} directive
stores/updates the value of the input field into/from a variable.
<div class="alert alert-info">
**Custom directives to access the DOM**: In Angular, the only place where an application should access the DOM is
**Custom directives to access the DOM**: In AngularJS, the only place where an application should access the DOM is
within directives. This is important because artifacts that access the DOM are hard to test.
If you need to access the DOM directly you should write a custom directive for this. The
{@link directive directives guide} explains how to do this.
@@ -76,12 +76,12 @@ stores/updates the value of the input field into/from a variable.
The second kind of new markup are the double curly braces `{{ expression | filter }}`:
When the compiler encounters this markup, it will replace it with the evaluated value of the markup.
An <a name="expression">{@link expression expression}</a> in a template is a JavaScript-like code snippet that allows
Angular to read and write variables. Note that those variables are not global variables.
AngularJS to read and write variables. Note that those variables are not global variables.
Just like variables in a JavaScript function live in a scope,
Angular provides a <a name="scope">{@link scope scope}</a> for the variables accessible to expressions.
AngularJS provides a <a name="scope">{@link scope scope}</a> for the variables accessible to expressions.
The values that are stored in variables on the scope are referred to as the <a name="model"></a>*model*
in the rest of the documentation.
Applied to the example above, the markup directs Angular to "take the data we got from the input widgets
Applied to the example above, the markup directs AngularJS to "take the data we got from the input widgets
and multiply them together".
The example above also contains a <a name="filter">{@link guide/filter filter}</a>.
@@ -89,7 +89,7 @@ A filter formats the value of an expression for display to the user.
In the example above, the filter {@link ng.filter:currency `currency`} formats a number
into an output that looks like money.
The important thing in the example is that Angular provides _live_ bindings:
The important thing in the example is that AngularJS provides _live_ bindings:
Whenever the input values change, the value of the expressions are automatically
recalculated and the DOM is updated with their values.
The concept behind this is <a name="databinding">{@link databinding two-way data binding}</a>.
@@ -157,9 +157,9 @@ expressions and directives.
Besides the new file that contains the controller code, we also added an
{@link ng.directive:ngController `ng-controller`} directive to the HTML.
This directive tells Angular that the new `InvoiceController` is responsible for the element with the directive
This directive tells AngularJS that the new `InvoiceController` is responsible for the element with the directive
and all of the element's children.
The syntax `InvoiceController as invoice` tells Angular to instantiate the controller
The syntax `InvoiceController as invoice` tells AngularJS to instantiate the controller
and save it in the variable `invoice` in the current scope.
We also changed all expressions in the page to read and write variables within that
@@ -260,22 +260,22 @@ get a hold of the now separated function?
This is where <a name="di">{@link di Dependency Injection}</a> comes into play.
Dependency Injection (DI) is a software design pattern that
deals with how objects and functions get created and how they get a hold of their dependencies.
Everything within Angular (directives, filters, controllers,
services, ...) is created and wired using dependency injection. Within Angular,
Everything within AngularJS (directives, filters, controllers,
services, ...) is created and wired using dependency injection. Within AngularJS,
the DI container is called the <a name="injector">{@link di injector}</a>.
To use DI, there needs to be a place where all the things that should work together are registered.
In Angular, this is the purpose of the <a name="module">{@link module modules}</a>.
When Angular starts, it will use the configuration of the module with the name defined by the `ng-app` directive,
In AngularJS, this is the purpose of the <a name="module">{@link module modules}</a>.
When AngularJS starts, it will use the configuration of the module with the name defined by the `ng-app` directive,
including the configuration of all modules that this module depends on.
In the example above:
The template contains the directive `ng-app="invoice2"`. This tells Angular
The template contains the directive `ng-app="invoice2"`. This tells AngularJS
to use the `invoice2` module as the main module for the application.
The code snippet `angular.module('invoice2', ['finance2'])` specifies that the `invoice2` module depends on the
`finance2` module. By this, Angular uses the `InvoiceController` as well as the `currencyConverter` service.
`finance2` module. By this, AngularJS uses the `InvoiceController` as well as the `currencyConverter` service.
Now that Angular knows of all the parts of the application, it needs to create them.
Now that AngularJS knows of all the parts of the application, it needs to create them.
In the previous section we saw that controllers are created using a constructor function.
For services, there are multiple ways to specify how they are created
(see the {@link services service guide}).
@@ -284,24 +284,24 @@ In the example above, we are using an anonymous function as the factory function
This function should return the `currencyConverter` service instance.
Back to the initial question: How does the `InvoiceController` get a reference to the `currencyConverter` function?
In Angular, this is done by simply defining arguments on the constructor function. With this, the injector
In AngularJS, this is done by simply defining arguments on the constructor function. With this, the injector
is able to create the objects in the right order and pass the previously created objects into the
factories of the objects that depend on them.
In our example, the `InvoiceController` has an argument named `currencyConverter`. By this, Angular knows about the
In our example, the `InvoiceController` has an argument named `currencyConverter`. By this, AngularJS knows about the
dependency between the controller and the service and calls the controller with the service instance as argument.
The last thing that changed in the example between the previous section and this section is that we
now pass an array to the `module.controller` function, instead of a plain function. The array first
contains the names of the service dependencies that the controller needs. The last entry
in the array is the controller constructor function.
Angular uses this array syntax to define the dependencies so that the DI also works after minifying
AngularJS uses this array syntax to define the dependencies so that the DI also works after minifying
the code, which will most probably rename the argument name of the controller constructor function
to something shorter like `a`.
## Accessing the backend
Let's finish our example by fetching the exchange rates from the [Fixer.io](http://fixer.io) exchange rate API.
The following example shows how this is done with Angular:
The following example shows how this is done with AngularJS:
<example name="guide-concepts-3" ng-app-included="true">
<file name="invoice3.js">
@@ -371,7 +371,7 @@ The following example shows how this is done with Angular:
What changed?
Our `currencyConverter` service of the `finance` module now uses the {@link ng.$http `$http`}, a
built-in service provided by Angular for accessing a server backend. `$http` is a wrapper around
built-in service provided by AngularJS for accessing a server backend. `$http` is a wrapper around
[`XMLHttpRequest`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
and [JSONP](http://en.wikipedia.org/wiki/JSONP) transports.
+33 -35
View File
@@ -5,16 +5,21 @@
# Understanding Controllers
In Angular, a Controller is defined by a JavaScript **constructor function** that is used to augment the
{@link scope Angular Scope}.
In AngularJS, a Controller is defined by a JavaScript **constructor function** that is used to augment the
{@link scope AngularJS Scope}.
When a Controller is attached to the DOM via the {@link ng.directive:ngController ng-controller}
directive, Angular will instantiate a new Controller object, using the specified Controller's
**constructor function**. A new **child scope** will be created and made available as an injectable
parameter to the Controller's constructor function as `$scope`.
Controllers can be attached to the DOM in different ways. For each of them, AngularJS will
instantiate a new Controller object, using the specified Controller's **constructor function**:
- the {@link ng.directive:ngController ngController} directive. A new **child scope** will be
created and made available as an injectable parameter to the Controller's constructor function
as `$scope`.
- a route controller in a {@link ngRoute.$routeProvider $route definition}.
- the controller of a {@link guide/directive regular directive}, or a
{@link guide/component component directive}.
If the controller has been attached using the `controller as` syntax then the controller instance will
be assigned to a property on the new scope.
be assigned to a property on the scope.
Use controllers to:
@@ -24,18 +29,27 @@ Use controllers to:
Do not use controllers to:
- Manipulate DOM — Controllers should contain only business logic.
Putting any presentation logic into Controllers significantly affects its testability. Angular
Putting any presentation logic into Controllers significantly affects its testability. AngularJS
has {@link databinding databinding} for most cases and {@link guide/directive directives} to
encapsulate manual DOM manipulation.
- Format input — Use {@link forms angular form controls} instead.
- Filter output — Use {@link guide/filter angular filters} instead.
- Share code or state across controllers — Use {@link services angular
- Format input — Use {@link forms AngularJS form controls} instead.
- Filter output — Use {@link guide/filter AngularJS filters} instead.
- Share code or state across controllers — Use {@link services AngularJS
services} instead.
- Manage the life-cycle of other components (for example, to create service instances).
In general, a Controller shouldn't try to do too much. It should contain only the business logic
needed for a single view.
The most common way to keep Controllers slim is by encapsulating work that doesn't belong to
controllers into services and then using these services in Controllers via dependency injection.
This is discussed in the {@link di Dependency Injection} and {@link services
Services} sections of this guide.
## Setting up the initial state of a `$scope` object
Typically, when you create an application you need to set up the initial state for the Angular
Typically, when you create an application you need to set up the initial state for the AngularJS
`$scope`. You set up the initial state of a scope by attaching properties to the `$scope` object.
The properties contain the **view model** (the model that will be presented by the view). All the
`$scope` properties will be available to the {@link templates template} at the point in the DOM where the Controller
@@ -52,13 +66,13 @@ myApp.controller('GreetingController', ['$scope', function($scope) {
}]);
```
We create an {@link module Angular Module}, `myApp`, for our application. Then we add the controller's
We create an {@link module AngularJS Module}, `myApp`, for our application. Then we add the controller's
constructor function to the module using the `.controller()` method. This keeps the controller's
constructor function out of the global scope.
<div class="alert alert-info">
We have used an **inline injection annotation** to explicitly specify the dependency
of the Controller on the `$scope` service provided by Angular. See the guide on
of the Controller on the `$scope` service provided by AngularJS. See the guide on
{@link guide/di Dependency Injection} for more information.
</div>
@@ -88,7 +102,7 @@ myApp.controller('DoubleController', ['$scope', function($scope) {
}]);
```
Once the Controller has been attached to the DOM, the `double` method can be invoked in an Angular
Once the Controller has been attached to the DOM, the `double` method can be invoked in an AngularJS
expression in the template:
```js
@@ -99,29 +113,13 @@ expression in the template:
As discussed in the {@link concepts Concepts} section of this guide, any
objects (or primitives) assigned to the scope become model properties. Any methods assigned to
the scope are available in the template/view, and can be invoked via angular expressions
the scope are available in the template/view, and can be invoked via AngularJS expressions
and `ng` event handler directives (e.g. {@link ng.directive:ngClick ngClick}).
## Using Controllers Correctly
In general, a Controller shouldn't try to do too much. It should contain only the business logic
needed for a single view.
The most common way to keep Controllers slim is by encapsulating work that doesn't belong to
controllers into services and then using these services in Controllers via dependency injection.
This is discussed in the {@link di Dependency Injection} and {@link services
Services} sections of this guide.
# Associating Controllers with Angular Scope Objects
You can associate Controllers with scope objects implicitly via the {@link ng.directive:ngController ngController
directive} or {@link ngRoute.$route $route service}.
## Simple Spicy Controller Example
To illustrate further how Controller components work in Angular, let's create a little app with the
To illustrate further how Controller components work in AngularJS, let's create a little app with the
following components:
- A {@link templates template} with two buttons and a simple message
@@ -159,7 +157,7 @@ string "very". Depending on which button is clicked, the `spice` model is set to
Things to notice in the example above:
- The `ng-controller` directive is used to (implicitly) create a scope for our template, and the
- The `ngController` directive is used to (implicitly) create a scope for our template, and the
scope is augmented (managed) by the `SpicyController` Controller.
- `SpicyController` is just a plain JavaScript function. As an (optional) naming convention the name
starts with capital letter and ends with "Controller".
@@ -262,7 +260,7 @@ Inheritance works with methods in the same way as it does with properties. So in
examples, all of the properties could be replaced with methods that return string values.
# Testing Controllers
## Testing Controllers
Although there are many ways to test a Controller, one of the best conventions, shown below,
involves injecting the {@link ng.$rootScope $rootScope} and {@link ng.$controller $controller}:
+10 -10
View File
@@ -4,38 +4,38 @@
@description
Angular sets these CSS classes. It is up to your application to provide useful styling.
AngularJS sets these CSS classes. It is up to your application to provide useful styling.
# CSS classes used by angular
# CSS classes used by AngularJS
* `ng-scope`
- **Usage:** angular applies this class to any element for which a new {@link $rootScope scope}
- **Usage:** AngularJS applies this class to any element for which a new {@link $rootScope scope}
is defined. (see {@link guide/scope scope} guide for more information about scopes)
* `ng-isolate-scope`
- **Usage:** angular applies this class to any element for which a new
- **Usage:** AngularJS applies this class to any element for which a new
{@link guide/directive#isolating-the-scope-of-a-directive isolate scope} is defined.
* `ng-binding`
- **Usage:** angular applies this class to any element that is attached to a data binding, via `ng-bind` or
- **Usage:** AngularJS applies this class to any element that is attached to a data binding, via `ng-bind` or
`{{}}` curly braces, for example. (see {@link guide/databinding databinding} guide)
* `ng-invalid`, `ng-valid`
- **Usage:** angular applies this class to a form control widget element if that element's input does
- **Usage:** AngularJS applies this class to a form control widget element if that element's input does
not pass validation. (see {@link ng.directive:input input} directive)
* `ng-pristine`, `ng-dirty`
- **Usage:** angular {@link ng.directive:ngModel ngModel} directive applies `ng-pristine` class
- **Usage:** AngularJS {@link ng.directive:ngModel ngModel} directive applies `ng-pristine` class
to a new form control widget which did not have user interaction. Once the user interacts with
the form control, the class is changed to `ng-dirty`.
* `ng-touched`, `ng-untouched`
- **Usage:** angular {@link ng.directive:ngModel ngModel} directive applies `ng-untouched` class
- **Usage:** AngularJS {@link ng.directive:ngModel ngModel} directive applies `ng-untouched` class
to a new form control widget which has not been blurred. Once the user blurs the form control,
the class is changed to `ng-touched`.
## Related Topics
* {@link guide/templates Angular Templates}
* {@link guide/forms Angular Forms}
* {@link guide/templates AngularJS Templates}
* {@link guide/forms AngularJS Forms}
+6 -6
View File
@@ -5,8 +5,8 @@
# Data Binding
Data-binding in Angular apps is the automatic synchronization of data between the model and view
components. The way that Angular implements data-binding lets you treat the model as the
Data-binding in AngularJS apps is the automatic synchronization of data between the model and view
components. The way that AngularJS implements data-binding lets you treat the model as the
single-source-of-truth in your application. The view is a projection of the model at all times.
When the model changes, the view reflects the change, and vice versa.
@@ -19,10 +19,10 @@ or related sections of the view are NOT automatically reflected in the view. Wor
that the user makes to the view are not reflected in the model. This means that the developer has
to write code that constantly syncs the view with the model and the model with the view.
## Data Binding in Angular Templates
## Data Binding in AngularJS Templates
<img class="right" src="img/Two_Way_Data_Binding.png"/><br />
Angular templates work differently. First the template (which is the uncompiled HTML along with
AngularJS templates work differently. First the template (which is the uncompiled HTML along with
any additional markup or directives) is compiled on the browser. The compilation step produces a
live view. Any changes to the view are immediately reflected in the model, and any changes in
the model are propagated to the view. The model is the single-source-of-truth for the application
@@ -36,5 +36,5 @@ isolation without the view and the related DOM/browser dependency.
## Related Topics
* {@link scope Angular Scopes}
* {@link templates Angular Templates}
* {@link scope AngularJS Scopes}
* {@link templates AngularJS Templates}
+1 -1
View File
@@ -13,7 +13,7 @@
## What are decorators?
Decorators are a design pattern that is used to separate modification or *decoration* of a class without modifying the
original source code. In Angular, decorators are functions that allow a service, directive or filter to be modified
original source code. In AngularJS, decorators are functions that allow a service, directive or filter to be modified
prior to its usage.
## How to use decorators
+32 -24
View File
@@ -8,32 +8,40 @@
Dependency Injection (DI) is a software design pattern that deals with how components get hold of
their dependencies.
The Angular injector subsystem is in charge of creating components, resolving their dependencies,
The AngularJS injector subsystem is in charge of creating components, resolving their dependencies,
and providing them to other components as requested.
## Using Dependency Injection
DI is pervasive throughout Angular. You can use it when defining components or when providing `run`
and `config` blocks for a module.
Dependency Injection is pervasive throughout AngularJS. You can use it when defining components
or when providing `run` and `config` blocks for a module.
- Components such as services, directives, filters, and animations are defined by an injectable
factory method or constructor function. These components can be injected with "service" and "value"
components as dependencies.
- {@link angular.Module#service Services}, {@link angular.Module#directive directives},
{@link angular.Module#filter filters}, and {@link angular.Module#animation animations} are
defined by an injectable factory method or constructor function, and can be injected with
"services", "values", and "constants" as dependencies.
- Controllers are defined by a constructor function, which can be injected with any of the "service"
and "value" components as dependencies, but they can also be provided with special dependencies. See
{@link di#controllers Controllers} below for a list of these special dependencies.
- {@link ng.$controller Controllers} are defined by a constructor function, which can be injected
with any of the "service" and "value" as dependencies, but they can also be provided with
"special dependencies". See {@link di#controllers Controllers} below for a list of these
special dependencies.
- The `run` method accepts a function, which can be injected with "service", "value" and "constant"
components as dependencies. Note that you cannot inject "providers" into `run` blocks.
- The {@link angular.Module#run `run`} method accepts a function, which can be injected with
"services", "values" and, "constants" as dependencies. Note that you cannot inject "providers"
into `run` blocks.
- The `config` method accepts a function, which can be injected with "provider" and "constant"
components as dependencies. Note that you cannot inject "service" or "value" components into
configuration.
- The {@link angular.Module#config `config`} method accepts a function, which can be injected with
"providers" and "constants" as dependencies. Note that you cannot inject "services" or
"values" into configuration.
See {@link module#module-loading-dependencies Modules} for more details about `run` and `config`
blocks.
- The {@link angular.Module#provider `provider`} method can only be injected with other "providers".
However, only those that have been **registered beforehand** can be injected. This is different
from services, where the order of registration does not matter.
See {@link module#module-loading Modules} for more details about `run` and `config`
blocks and {@link guide/providers Providers} for more information about the different provider
types.
### Factory Methods
@@ -100,7 +108,7 @@ Moreover, additional dependencies are made available to Controllers:
## Dependency Annotation
Angular invokes certain functions (like service factories and controllers) via the injector.
AngularJS invokes certain functions (like service factories and controllers) via the injector.
You need to annotate these functions so that the injector knows what services to inject into
the function. There are three ways of annotating your code with service name information:
@@ -204,11 +212,11 @@ angular.module('myApp', [])
// $rootScope is implicitly injected
})
.run(['willBreak', function(willBreak) {
// Angular will throw when this runs
// AngularJS will throw when this runs
}]);
```
When the `willBreak` service is instantiated, Angular will throw an error because of strict mode.
When the `willBreak` service is instantiated, AngularJS will throw an error because of strict mode.
This is useful when using a tool like [ng-annotate](https://github.com/olov/ng-annotate) to
ensure that all of your application components have annotations.
@@ -225,7 +233,7 @@ angular.bootstrap(document, ['myApp'], {
## Why Dependency Injection?
This section motivates and explains Angular's use of DI. For how to use DI, see above.
This section motivates and explains AngularJS's use of DI. For how to use DI, see above.
For in-depth discussion about DI, see
[Dependency Injection](http://en.wikipedia.org/wiki/Dependency_injection) at Wikipedia,
@@ -264,7 +272,7 @@ code that constructs `SomeClass`.
<img class="pull-right" style="padding-left: 3em; padding-bottom: 1em;" src="img/guide/concepts-module-injector.png">
To manage the responsibility of dependency creation, each Angular application has an {@link
To manage the responsibility of dependency creation, each AngularJS application has an {@link
angular.injector injector}. The injector is a
[service locator](http://en.wikipedia.org/wiki/Service_locator_pattern) that is responsible for
construction and lookup of dependencies.
@@ -290,7 +298,7 @@ myModule.factory('greeter', function($window) {
```
Create a new injector that can provide components defined in our `myModule` module and request our
`greeter` service from the injector. (This is usually done automatically by angular bootstrap).
`greeter` service from the injector. (This is usually done automatically by AngularJS bootstrap).
```js
var injector = angular.injector(['ng', 'myModule']);
@@ -317,7 +325,7 @@ function MyController($scope, greeter) {
}
```
When Angular compiles the HTML, it processes the `ng-controller` directive, which in turn
When AngularJS compiles the HTML, it processes the `ng-controller` directive, which in turn
asks the injector to create an instance of the controller and its dependencies.
```js
@@ -332,6 +340,6 @@ This is the best outcome. The application code simply declares the dependencies
having to deal with the injector. This setup does not break the Law of Demeter.
<div class="alert alert-info">
**Note:** Angular uses
**Note:** AngularJS uses
[**constructor injection**](http://misko.hevery.com/2009/02/19/constructor-injection-vs-setter-injection/).
</div>
+9 -9
View File
@@ -24,9 +24,9 @@ name, comment or CSS class) that tell AngularJS's **HTML compiler** ({@link ng.$
to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform
the DOM element and its children.
Angular comes with a set of these directives built-in, like `ngBind`, `ngModel`, and `ngClass`.
Much like you create controllers and services, you can create your own directives for Angular to use.
When Angular {@link guide/bootstrap bootstraps} your application, the
AngularJS comes with a set of these directives built-in, like `ngBind`, `ngModel`, and `ngClass`.
Much like you create controllers and services, you can create your own directives for AngularJS to use.
When AngularJS {@link guide/bootstrap bootstraps} your application, the
{@link guide/compiler HTML compiler} traverses the DOM matching directives against the DOM elements.
<div class="alert alert-info">
@@ -41,7 +41,7 @@ mirrors the process of compiling source code in
## Matching Directives
Before we can write a directive, we need to know how Angular's {@link guide/compiler HTML compiler}
Before we can write a directive, we need to know how AngularJS's {@link guide/compiler HTML compiler}
determines when to use a given directive.
Similar to the terminology used when an [element **matches** a selector](https://developer.mozilla.org/en-US/docs/Web/API/Element.matches), we say an element **matches** a
@@ -67,7 +67,7 @@ And the following `<person>` element **matches** the `person` directive:
### Normalization
Angular **normalizes** an element's tag and attribute name to determine which elements match which
AngularJS **normalizes** an element's tag and attribute name to determine which elements match which
directives. We typically refer to directives by their case-sensitive
[camelCase](http://en.wikipedia.org/wiki/CamelCase) **normalized** name (e.g. `ngModel`).
However, since HTML is case-insensitive, we refer to directives in the DOM by lower-case
@@ -178,7 +178,7 @@ and compilation process.
directive names. For instance, if you created a `<carousel>` directive, it would be problematic if HTML7
introduced the same element. A two or three letter prefix (e.g. `btfCarousel`) works well. Similarly, do
not prefix your own directives with `ng` or they might conflict with directives included in a future
version of Angular.
version of AngularJS.
</div>
For the following examples, we'll use the prefix `my` (e.g. `myCustomer`).
@@ -257,7 +257,7 @@ using `templateUrl` instead:
</example>
`templateUrl` can also be a function which returns the URL of an HTML template to be loaded and
used for the directive. Angular will call the `templateUrl` function with two parameters: the
used for the directive. AngularJS will call the `templateUrl` function with two parameters: the
element that the directive was called on, and an `attr` object associated with that element.
<div class="alert alert-warning">
@@ -544,7 +544,7 @@ directive logic will be put.
`link` takes a function with the following signature,
`function link(scope, element, attrs, controller, transcludeFn) { ... }`, where:
* `scope` is an Angular scope object.
* `scope` is an AngularJS scope object.
* `element` is the jqLite-wrapped element that this directive matches.
* `attrs` is a hash object with key-value pairs of normalized attribute names and their
corresponding attribute values.
@@ -614,7 +614,7 @@ function.
We register an event `element.on('$destroy', ...)`. What fires this `$destroy` event?
There are a few special events that AngularJS emits. When a DOM node that has been compiled
with Angular's compiler is destroyed, it emits a `$destroy` event. Similarly, when an AngularJS
with AngularJS's compiler is destroyed, it emits a `$destroy` event. Similarly, when an AngularJS
scope is destroyed, it broadcasts a `$destroy` event to listening scopes.
By listening to this event, you can remove event listeners that might cause memory leaks.
+4 -4
View File
@@ -7,8 +7,8 @@
<div class="alert alert-danger">
**Note:** In the past, end-to-end testing could be done with a deprecated tool called
[Angular Scenario Runner](http://code.angularjs.org/1.2.16/docs/guide/e2e-testing). That tool
is now in maintenance mode.
[AngularJS Scenario Runner](http://code.angularjs.org/1.2.16/docs/guide/e2e-testing). That tool
is now in maintenance mode, and will be removed in version 1.7.0.
</div>
As applications grow in size and complexity, it becomes unrealistic to rely on manual testing to
@@ -19,7 +19,7 @@ these problems.
We have built [Protractor](https://github.com/angular/protractor), an end
to end test runner which simulates user interactions that will help you verify the health of your
Angular application.
AngularJS application.
## Using Protractor
@@ -76,7 +76,7 @@ filter the list of items.
## Example
See the [angular-seed](https://github.com/angular/angular-seed) project for more examples, or look
at the embedded examples in the Angular documentation (For example, {@link $http $http}
at the embedded examples in the AngularJS documentation (For example, {@link $http $http}
has an end-to-end test in the example under the `protractor.js` tag).
## Caveats
+17 -17
View File
@@ -3,13 +3,13 @@
@sortOrder 270
@description
# Angular Expressions
# AngularJS Expressions
Angular expressions are JavaScript-like code snippets that are mainly placed in
AngularJS expressions are JavaScript-like code snippets that are mainly placed in
interpolation bindings such as `<span title="{{ attrBinding }}">{{ textBinding }}</span>`,
but also used directly in directive attributes such as `ng-click="functionExpression()"`.
For example, these are valid expressions in Angular:
For example, these are valid expressions in AngularJS:
* `1+2`
* `a+b`
@@ -17,38 +17,38 @@ For example, these are valid expressions in Angular:
* `items[index]`
## Angular Expressions vs. JavaScript Expressions
## AngularJS Expressions vs. JavaScript Expressions
Angular expressions are like JavaScript expressions with the following differences:
AngularJS expressions are like JavaScript expressions with the following differences:
* **Context:** JavaScript expressions are evaluated against the global `window`.
In Angular, expressions are evaluated against a {@link ng.$rootScope.Scope `scope`} object.
In AngularJS, expressions are evaluated against a {@link ng.$rootScope.Scope `scope`} object.
* **Forgiving:** In JavaScript, trying to evaluate undefined properties generates `ReferenceError`
or `TypeError`. In Angular, expression evaluation is forgiving to `undefined` and `null`.
or `TypeError`. In AngularJS, expression evaluation is forgiving to `undefined` and `null`.
* **Filters:** You can use {@link guide/filter filters} within expressions to format data before
displaying it.
* **No Control Flow Statements:** You cannot use the following in an Angular expression:
* **No Control Flow Statements:** You cannot use the following in an AngularJS expression:
conditionals, loops, or exceptions.
* **No Function Declarations:** You cannot declare functions in an Angular expression,
* **No Function Declarations:** You cannot declare functions in an AngularJS expression,
even inside `ng-init` directive.
* **No RegExp Creation With Literal Notation:** You cannot create regular expressions
in an AngularJS expression. An exception to this rule is {@link ngPattern `ng-pattern`} which accepts valid
RegExp.
in an AngularJS expression. An exception to this rule is {@link ngPattern `ng-pattern`} which
accepts valid RegExp.
* **No Object Creation With New Operator:** You cannot use `new` operator in an Angular expression.
* **No Object Creation With New Operator:** You cannot use `new` operator in an AngularJS expression.
* **No Bitwise, Comma, And Void Operators:** You cannot use
[Bitwise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators),
`,` or `void` operators in an Angular expression.
`,` or `void` operators in an AngularJS expression.
If you want to run more complex JavaScript code, you should make it a controller method and call
the method from your view. If you want to `eval()` an Angular expression yourself, use the
the method from your view. If you want to `eval()` an AngularJS expression yourself, use the
{@link ng.$rootScope.Scope#$eval `$eval()`} method.
## Example
@@ -111,10 +111,10 @@ You can try evaluating different expressions here:
## Context
Angular does not use JavaScript's `eval()` to evaluate expressions. Instead Angular's
AngularJS does not use JavaScript's `eval()` to evaluate expressions. Instead AngularJS's
{@link ng.$parse $parse} service processes these expressions.
Angular expressions do not have direct access to global variables like `window`, `document` or `location`.
AngularJS expressions do not have direct access to global variables like `window`, `document` or `location`.
This restriction is intentional. It prevents accidental access to the global state a common source of subtle bugs.
Instead use services like `$window` and `$location` in functions on controllers, which are then called from expressions.
@@ -181,7 +181,7 @@ Similarly, invoking a function `a.b.c()` on `undefined` or `null` simply returns
## No Control Flow Statements
Apart from the ternary operator (`a ? b : c`), you cannot write a control flow statement in an
expression. The reason behind this is core to the Angular philosophy that application logic should
expression. The reason behind this is core to the AngularJS philosophy that application logic should
be in controllers, not the views. If you need a real conditional, loop, or to throw from a view
expression, delegate to a JavaScript method instead.
+14 -14
View File
@@ -3,9 +3,9 @@
@sortOrder 150
@description
# External Angular 1 Resources
# External AngularJS Resources
This is a collection of external, 3rd party resources for learning and developing Angular.
This is a collection of external, 3rd party resources for learning and developing AngularJS.
## Articles, Videos, and Projects
@@ -21,7 +21,7 @@ This is a collection of external, 3rd party resources for learning and developin
#### Application Structure & Style Guides
* [Angular Styleguide](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md)
* [AngularJS Styleguide](https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md)
* [Architecture, file structure, components, one-way dataflow and best practices](https://github.com/toddmotto/angular-styleguide)
* [When to use directives, controllers or services](http://kirkbushell.me/when-to-use-directives-controllers-or-services-in-angular/)
* [Service vs Factory](http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html)
@@ -32,8 +32,8 @@ This is a collection of external, 3rd party resources for learning and developin
#### Mobile
* [Angular on Mobile Guide](http://www.ng-newsletter.com/posts/angular-on-mobile.html)
* [Angular and Cordova](http://devgirl.org/2013/06/10/quick-start-guide-phonegap-and-angularjs/)
* [AngularJS on Mobile Guide](http://www.ng-newsletter.com/posts/angular-on-mobile.html)
* [AngularJS and Cordova](http://devgirl.org/2013/06/10/quick-start-guide-phonegap-and-angularjs/)
* [Ionic Framework](http://ionicframework.com/)
#### Deployment
@@ -48,7 +48,7 @@ This is a collection of external, 3rd party resources for learning and developin
* **Django:** [Tutorial](http://blog.mourafiq.com/post/55034504632/end-to-end-web-app-with-django-rest-framework), [Integrating AngularJS with Django](http://django-angular.readthedocs.org/en/latest/integration.html), [Getting Started with Django Rest Framework and AngularJS](http://blog.kevinastone.com/getting-started-with-django-rest-framework-and-angularjs.html)
* **FireBase:** [AngularFire](http://angularfire.com/), [Realtime Apps with AngularJS and FireBase (video)](http://www.youtube.com/watch?v=C7ZI7z7qnHU)
* **Google Cloud Platform: **[with Cloud Endpoints](https://cloud.google.com/developers/articles/angularjs-cloud-endpoints-recipe-for-building-modern-web-applications/), [with Go](https://github.com/GoogleCloudPlatform/appengine-angular-gotodos)
* **Google Cloud Platform:** [with Go](https://github.com/GoogleCloudPlatform/appengine-angular-gotodos)
* **Hood.ie:** [60 Minutes to Awesome](http://www.roberthorvick.com/2013/06/30/todomvc-angularjs-hood-ie-60-minutes-to-awesome/)
* **MEAN Stack: **[Blog post](http://blog.mongodb.org/post/49262866911/the-mean-stack-mongodb-expressjs-angularjs-and), [Setup](http://thecodebarbarian.wordpress.com/2013/07/22/introduction-to-the-mean-stack-part-one-setting-up-your-tools/), [GDL Video](https://developers.google.com/live/shows/913996610)
* **Rails: **[Tutorial](http://coderberry.me/blog/2013/04/22/angularjs-on-rails-4-part-1/), [AngularJS with Rails4](https://shellycloud.com/blog/2013/10/how-to-integrate-angularjs-with-rails-4), [angularjs-rails](https://github.com/hiravgandhi/angularjs-rails)
@@ -75,12 +75,12 @@ This is a collection of external, 3rd party resources for learning and developin
* **Getting Started:** [Comparison of the options for starting a new project](http://www.dancancro.com/comparison-of-angularjs-application-starters/)
* **Debugging:** [Batarang](https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk?hl=en)
* **Editor support:** [Webstorm](http://plugins.jetbrains.com/plugin/6971) (and [video](http://www.youtube.com/watch?v=LJOyrSh1kDU)), [Sublime Text](https://github.com/angular-ui/AngularJS-sublime-package), [Visual Studio](http://madskristensen.net/post/angularjs-intellisense-in-visual-studio-2012), [Atom](https://github.com/angular-ui/AngularJS-Atom), [Vim](https://github.com/burnettk/vim-angular)
* **Workflow:** [Yeoman.io](https://github.com/yeoman/generator-angular) and [Angular Yeoman Tutorial](http://www.sitepoint.com/kickstart-your-angularjs-development-with-yeoman-grunt-and-bower/)
* **Workflow:** [Yeoman.io](https://github.com/yeoman/generator-angular) and [AngularJS Yeoman Tutorial](http://www.sitepoint.com/kickstart-your-angularjs-development-with-yeoman-grunt-and-bower/)
## Complementary Libraries
This is a list of libraries that enhance Angular, add common UI components or integrate with other libraries.
You can find a larger list of Angular external libraries at [ngmodules.org](http://ngmodules.org/).
This is a list of libraries that enhance AngularJS, add common UI components or integrate with other libraries.
You can find a larger list of AngularJS external libraries at [ngmodules.org](http://ngmodules.org/).
* **Advanced Routing:** [UI-Router](https://github.com/angular-ui/ui-router)
* **Authentication:** [Http Auth Interceptor](https://github.com/witoldsz/angular-http-auth)
@@ -98,21 +98,21 @@ You can find a larger list of Angular external libraries at [ngmodules.org](http
- Data Modeling [JS-Data-Angular](https://github.com/js-data/js-data-angular)
* **Fileupload:**
- [ng-file-upload](https://github.com/danialfarid/ng-file-upload)
- [blueimp-fileupload for Angular](https://blueimp.github.io/jQuery-File-Upload/angularjs.html)
- [blueimp-fileupload for AngularJS](https://blueimp.github.io/jQuery-File-Upload/angularjs.html)
* **General UI Libraries:**
- [Angular Material](https://material.angularjs.org/latest/)
- [Angular UI Bootstrap](http://angular-ui.github.io/)
- [AngularJS Material](https://material.angularjs.org/latest/)
- [AngularJS UI Bootstrap](http://angular-ui.github.io/)
- [AngularStrap for Bootstrap 3](http://mgcrea.github.io/angular-strap/)
- [KendoUI](http://kendo-labs.github.io/angular-kendo/#/)
- [Wijmo](http://wijmo.com/tag/angularjs-2/)
* **Specific UI Elements:**
- [ngInfiniteScroll](https://sroze.github.io/ngInfiniteScroll/)
- [ngTable](https://github.com/esvit/ng-table)
- [Angular UI Grid](http://angular-ui.github.io/grid)
- [AngularJS UI Grid](http://angular-ui.github.io/grid)
- [Toaster Notifications](https://github.com/jirikavi/AngularJS-Toaster)
- [textAngular Rich Text Editor / contenteditable](http://textangular.com/) (Rich Text Editor /
binding to contenteditable)
- [Angular UI Map (Google Maps)](https://github.com/angular-ui/ui-map)
- [AngularJS UI Map (Google Maps)](https://github.com/angular-ui/ui-map)
## General Learning Resources
+5 -5
View File
@@ -6,7 +6,7 @@
# Filters
Filters format the value of an expression for display to the user. They can be used in view
templates, controllers or services. Angular comes with a collection of
templates, controllers or services. AngularJS comes with a collection of
[built-in filters](api/ng/filter), but it is easy to define your own as well.
The underlying API is the {@link ng.$filterProvider}.
@@ -44,7 +44,7 @@ as inputs. Filters that receive [Objects](https://developer.mozilla.org/en-US/do
as input are executed on each `$digest`, as it would be too costly to track if the inputs have changed.
2. Filters that are marked as `$stateful` are also executed on each $digest.
See {@link guide/filter#stateful-filters Stateful filters} for more information. Note that no Angular
See {@link guide/filter#stateful-filters Stateful filters} for more information. Note that no AngularJS
core filters are $stateful.
@@ -110,12 +110,12 @@ function.
The filter function should be a [pure function](http://en.wikipedia.org/wiki/Pure_function), which
means that it should always return the same result given the same input arguments and should not affect
external state, for example, other Angular services. Angular relies on this contract and will by default
external state, for example, other AngularJS services. AngularJS relies on this contract and will by default
execute a filter only when the inputs to the function change.
{@link guide/filter#stateful-filters Stateful filters} are possible, but less performant.
<div class="alert alert-warning">
**Note:** Filter names must be valid angular {@link expression} identifiers, such as `uppercase` or `orderBy`.
**Note:** Filter names must be valid AngularJS {@link expression} identifiers, such as `uppercase` or `orderBy`.
Names with special characters, such as hyphens and dots, are not allowed. If you wish to namespace
your filters, then you can use capitalization (`myappSubsectionFilterx`) or underscores
(`myapp_subsection_filterx`).
@@ -162,7 +162,7 @@ text upper-case.
### Stateful filters
It is strongly discouraged to write filters that are stateful, because the execution of those can't
be optimized by Angular, which often leads to performance issues. Many stateful filters can be
be optimized by AngularJS, which often leads to performance issues. Many stateful filters can be
converted into stateless filters just by exposing the hidden state as a model and turning it into an
argument for the filter.
+6 -6
View File
@@ -303,7 +303,7 @@ after last change.
## Custom Validation
Angular provides basic implementation for most common HTML5 {@link ng.directive:input input}
AngularJS provides basic implementation for most common HTML5 {@link ng.directive:input input}
types: ({@link input[text] text}, {@link input[number] number}, {@link input[url] url},
{@link input[email] email}, {@link input[date] date}, {@link input[radio] radio}, {@link input[checkbox] checkbox}),
as well as some directives for validation (`required`, `pattern`, `minlength`, `maxlength`,
@@ -314,7 +314,7 @@ the {@link ngModel.NgModelController `ngModelController`}. To get a hold of the
you require it in the directive as shown in the example below.
Each function in the `$validators` object receives the `modelValue` and the `viewValue`
as parameters. Angular will then call `$setValidity` internally with the function's return value
as parameters. AngularJS will then call `$setValidity` internally with the function's return value
(`true`: valid, `false`: invalid). The validation functions are executed every time an input
is changed (`$setViewValue` is called) or whenever the bound `model` changes.
Validation happens after successfully running `$parsers` and `$formatters`, respectively.
@@ -422,7 +422,7 @@ In the following example we create two directives:
## Modifying built-in validators
Since Angular itself uses `$validators`, you can easily replace or remove built-in validators,
Since AngularJS itself uses `$validators`, you can easily replace or remove built-in validators,
should you find it necessary. The following example shows you how to overwrite the email validator
in `input[email]` from a custom directive so that it requires a specific top-level domain,
`example.com` to be present.
@@ -451,10 +451,10 @@ Note that you can alternatively use `ng-pattern` to further restrict the validat
return {
require: '?ngModel',
link: function(scope, elm, attrs, ctrl) {
// only apply the validator if ngModel is present and Angular has added the email validator
// only apply the validator if ngModel is present and AngularJS has added the email validator
if (ctrl && ctrl.$validators.email) {
// this will overwrite the default Angular email validator
// this will overwrite the default AngularJS email validator
ctrl.$validators.email = function(modelValue) {
return ctrl.$isEmpty(modelValue) || EMAIL_REGEXP.test(modelValue);
};
@@ -467,7 +467,7 @@ Note that you can alternatively use `ng-pattern` to further restrict the validat
## Implementing custom form controls (using `ngModel`)
Angular implements all of the basic HTML form controls ({@link ng.directive:input input},
AngularJS implements all of the basic HTML form controls ({@link ng.directive:input input},
{@link ng.directive:select select}, {@link ng.directive:textarea textarea}),
which should be sufficient for most cases. However, if you need more flexibility,
you can write your own form control as a directive.
+28 -28
View File
@@ -13,9 +13,9 @@ other locale-specific bits (such as date or currency formats) out of the applica
application means providing translations and localized formats for the abstracted bits.
## How does Angular support i18n/l10n?
## How does AngularJS support i18n/l10n?
Angular supports i18n/l10n for {@link ng.filter:date date}, {@link ng.filter:number number} and
AngularJS supports i18n/l10n for {@link ng.filter:date date}, {@link ng.filter:number number} and
{@link ng.filter:currency currency} filters.
Localizable pluralization is supported via the {@link ng.directive:ngPluralize `ngPluralize`
@@ -23,11 +23,11 @@ directive}. Additionally, you can use {@link guide/i18n#messageformat-extension
`$interpolate` for localizable pluralization and gender support in all interpolations via the
`ngMessageFormat` module.
All localizable Angular components depend on locale-specific rule sets managed by the {@link
All localizable AngularJS components depend on locale-specific rule sets managed by the {@link
ng.$locale `$locale` service}.
There are a few examples that showcase how to use Angular filters with various locale rule sets in the
[`i18n/e2e` directory](https://github.com/angular/angular.js/tree/master/i18n/e2e) of the Angular
There are a few examples that showcase how to use AngularJS filters with various locale rule sets in the
[`i18n/e2e` directory](https://github.com/angular/angular.js/tree/master/i18n/e2e) of the AngularJS
source code.
@@ -41,20 +41,20 @@ also valid. See the [ICU](http://userguide.icu-project.org/locale) website for m
about using locale IDs.
## Supported locales in Angular
## Supported locales in AngularJS
Angular separates number and datetime format rule sets into different files, each file for a
AngularJS separates number and datetime format rule sets into different files, each file for a
particular locale. You can find a list of currently supported locales
[here](https://github.com/angular/angular.js/tree/master/src/ngLocale)
## Providing locale rules to Angular
## Providing locale rules to AngularJS
There are two approaches to providing locale rules to Angular:
There are two approaches to providing locale rules to AngularJS:
### 1. Pre-bundled rule sets
You can pre-bundle the desired locale file with Angular by concatenating the content of the
You can pre-bundle the desired locale file with AngularJS by concatenating the content of the
locale-specific file to the end of `angular.js` or `angular.min.js` file.
For example on *nix, to create an angular.js file that contains localization rules for german
@@ -63,7 +63,7 @@ locale, you can do the following:
`cat angular.js i18n/angular-locale_de-de.js > angular_de-de.js`
When the application containing `angular_de-de.js` script instead of the generic angular.js script
starts, Angular is automatically pre-configured with localization rules for the german locale.
starts, AngularJS is automatically pre-configured with localization rules for the german locale.
### 2. Including a locale script in `index.html`
@@ -93,12 +93,12 @@ an extra script needs to be loaded.
## Caveats
Although Angular makes i18n convenient, there are several things you need to be conscious of as you
Although AngularJS makes i18n convenient, there are several things you need to be conscious of as you
develop your app.
### Currency symbol
Angular's {@link ng.filter:currency currency filter} allows you to use the default currency symbol
AngularJS's {@link ng.filter:currency currency filter} allows you to use the default currency symbol
from the {@link ng.$locale locale service}, or you can provide the filter with a custom currency
symbol.
@@ -122,7 +122,7 @@ This is problematic because $1000 is not the same as ¥1000.
In this case, you need to override the default currency symbol by providing the
{@link ng.filter:currency} currency filter with a currency symbol as a parameter.
If we change the above to `{{ 1000 | currency:"USD$"}}`, Angular will always show a balance of
If we change the above to `{{ 1000 | currency:"USD$"}}`, AngularJS will always show a balance of
`USD$1000` regardless of locale.
### Translation length
@@ -135,16 +135,16 @@ as expected even when their contents vary greatly in content size.
### Timezones
The Angular datetime filter uses the time zone settings of the browser. The same
The AngularJS datetime filter uses the time zone settings of the browser. The same
application will show different time information depending on the time zone settings of the
computer that the application is running on. Neither JavaScript nor Angular currently supports
computer that the application is running on. Neither JavaScript nor AngularJS currently supports
displaying the date with a timezone specified by the developer.
<a name="MessageFormat"></a>
## MessageFormat extensions
You can write localizable plural and gender based messages in Angular interpolation expressions and
You can write localizable plural and gender based messages in AngularJS interpolation expressions and
`$interpolate` calls.
This syntax extension is provided by way of the `ngMessageFormat` module that your application can
@@ -271,7 +271,7 @@ actual message text that occurs in curly braces. Whitespace is generally used t
Here, `NUMERIC_EXPRESSION` is an expression that evaluates to a numeric value based on which the
displayed message should change based on pluralization rules.
Following the Angular expression, you would denote the plural extension syntax by the `, plural,`
Following the AngularJS expression, you would denote the plural extension syntax by the `, plural,`
syntax element. The spaces there are optional.
This is followed by a list of selection keyword and corresponding message pairs. The "other"
@@ -303,7 +303,7 @@ later.)
#### Messages
Messages immediately follow a selection keyword and are optionally preceded by whitespace. They are
written in single curly braces (`{}`). They may contain Angular interpolation syntax inside them.
written in single curly braces (`{}`). They may contain AngularJS interpolation syntax inside them.
In addition, the `#` symbol is a placeholder for the actual numeric value of the expression.
### Simple plural example
@@ -316,7 +316,7 @@ In addition, the `#` symbol is a placeholder for the actual numeric value of the
}}
```
Because these messages can themselves contain Angular expressions, you could also write this as
Because these messages can themselves contain AngularJS expressions, you could also write this as
follows:
```text
@@ -342,7 +342,7 @@ explain this with an example.
}}
```
When an `offset` is specified, the matching works as follows. First, the exact value of the Angular
When an `offset` is specified, the matching works as follows. First, the exact value of the AngularJS
expression is matched against the exact matches (i.e. `=N` selectors) to find a match. If there is
one, that message is used. If there was no match, then the offset value is subtracted from the
value of the expression and locale specific pluralization rules are applied to this new value to
@@ -379,10 +379,10 @@ The syntax for gender based message selection looks like the following:
Please note that whitespace (including newline) is generally insignificant except as part of the
actual message text that occurs in curly braces. Whitespace is generally used to aid readability.
Here, `EXPRESSION` is an Angular expression that evaluates to the gender of the person that
Here, `EXPRESSION` is an AngularJS expression that evaluates to the gender of the person that
is used to select the message that should be displayed.
The Angular expression is followed by `, select,` where the spaces are optional.
The AngularJS expression is followed by `, select,` where the spaces are optional.
This is followed by a list of selection keyword and corresponding message pairs. The "other"
keyword and corresponding message are **required** but you may have as few or as many of the other
@@ -392,13 +392,13 @@ matching is **case-sensitive**.
#### Selection Keywords
Selection keywords are simple words like "male" and "female". The keyword, "other", and its
corresponding message are required while others are optional. It is used when the Angular
corresponding message are required while others are optional. It is used when the AngularJS
expression does not match (case-insensitively) any of the other keywords specified.
#### Messages
Messages immediately follow a selection keyword and are optionally preceded by whitespace. They are
written in single curly braces (`{}`). They may contain Angular interpolation syntax inside them.
written in single curly braces (`{}`). They may contain AngularJS interpolation syntax inside them.
### Simple gender example
@@ -412,8 +412,8 @@ written in single curly braces (`{}`). They may contain Angular interpolation s
### Nesting
As mentioned in the syntax for plural and select, the embedded messages can contain Angular
interpolation syntax. Since you can use MessageFormat extensions in Angular interpolation, this
As mentioned in the syntax for plural and select, the embedded messages can contain AngularJS
interpolation syntax. Since you can use MessageFormat extensions in AngularJS interpolation, this
allows you to nest plural and gender expressions in any order.
Please note that if these are intended to reach a translator and be translated, it is recommended
@@ -450,7 +450,7 @@ This syntax extension, while based on MessageFormat, has been designed to be bac
with existing AngularJS interpolation expressions. The key rule is simply this: **All
interpolations are done inside double curlies.** The top level comma operator after an expression
inside the double curlies causes MessageFormat extensions to be recognized. Such a top level comma
is otherwise illegal in an Angular expression and is used by MessageFormat to specify the function
is otherwise illegal in an AngularJS expression and is used by MessageFormat to specify the function
(such as plural/select) and it's related syntax.
To understand the extension, take a look at the ICU MessageFormat syntax as specified by the ICU
+13 -4
View File
@@ -13,7 +13,7 @@ addressing issues specific to IE8 or earlier.
</div>
This document describes the Internet Explorer (IE) idiosyncrasies when dealing with custom HTML
attributes and tags. Read this document if you are planning on deploying your Angular application
attributes and tags. Read this document if you are planning on deploying your AngularJS application
on IE.
The project currently supports and will attempt to fix bugs for IE9 and above. The continuous
@@ -25,17 +25,26 @@ We do not run tests on IE8 and below. A subset of the AngularJS functionality ma
browsers, but it is up to you to test and decide whether it works for your particular app.
To ensure your Angular application works on IE please consider:
To ensure your AngularJS application works on IE please consider:
1. Use `ng-style` tags instead of `style="{{ someCss }}"`. The latter works in Chrome, Firefox,
Safari and Edge but does not work in Internet Explorer (even 11).
2. For the `type` attribute of buttons, use `ng-attr-type` tags instead of
`type="{{ someExpression }}"`. If using the latter, Internet Explorer overwrites the expression
with `type="submit"` before Angular has a chance to interpolate it.
with `type="submit"` before AngularJS has a chance to interpolate it.
3. For the `value` attribute of progress, use `ng-attr-value` tags instead of
`value="{{ someExpression}}"`. If using the latter, Internet Explorer overwrites the expression
with `value="0"` before Angular has a chance to interpolate it.
with `value="0"` before AngularJS has a chance to interpolate it.
4. For the `placeholder` attribute of textarea, use `ng-attr-placeholder` tags instead
of `placeholder="{{ someExpression }}"`. If using the latter, Internet Explorer will error
on accessing the `nodeValue` on a parentless `TextNode` in Internet Explorer 10 & 11
(see [issue 5025](https://github.com/angular/angular.js/issues/5025)).
5. Using the `disabled` attribute on an element that has
descendant form controls can result in unexpected behavior in Internet Explorer 11.
For example, the value of descendant input elements with `ng-model` will not reflect
the model (or changes to the model), and the value of the `placeholder` attribute will be
inserted as the input's value. Descendant select elements will also be inoperable, as if they
had the `disabled` attribute applied to them, which may not be the intended effect.
To work around this unexpected behavior, 1) avoid using the identifier `disabled` for custom attribute
directives that are on elements with descendant form controls, and 2) avoid using `disabled` as an identifier
for an attribute passed to a custom directive that has descendant form controls.
+19 -19
View File
@@ -2,26 +2,26 @@
@name Developer Guide
@description
# Guide to Angular 1 Documentation
# Guide to AngularJS Documentation
On this page, you will find a list of official Angular resources on various topics.
On this page, you will find a list of official AngularJS resources on various topics.
Just starting out with Angular 1? Try working through our step by step tutorial or try
Just starting out with AngularJS? Try working through our step by step tutorial or try
building on our seed project.
* {@link tutorial/index Official Angular 1 Tutorial}
* [Angular Seed](https://github.com/angular/angular-seed)
* {@link tutorial/index Official AngularJS Tutorial}
* [AngularJS Seed](https://github.com/angular/angular-seed)
Ready to find out more about Angular 1?
Ready to find out more about AngularJS?
* {@link guide/introduction What is Angular 1?}
* {@link guide/introduction What is AngularJS?}
* {@link guide/concepts Conceptual Overview}
## Core Concepts
### Templates
In Angular applications, you move the job of filling page templates with data from the server to the client. The result is a system better structured for dynamic page updates. Below are the core features you'll use.
In AngularJS applications, you move the job of filling page templates with data from the server to the client. The result is a system better structured for dynamic page updates. Below are the core features you'll use.
* {@link guide/databinding Data binding}
* {@link guide/expression Expressions}
@@ -43,7 +43,7 @@ In Angular applications, you move the job of filling page templates with data fr
* **Animation:** {@link guide/animations Core concepts}, {@link ngAnimate ngAnimate API}
* **Security:** {@link guide/security Security Docs}, {@link ng.$sce Strict Contextual Escaping}, {@link ng.directive:ngCsp Content Security Policy}, {@link ngSanitize.$sanitize $sanitize}, [video](https://www.youtube.com/watch?v=18ifoT-Id54)
* **Internationalization and Localization:** {@link guide/i18n Angular Guide to i18n and l10n}, {@link ng.filter:date date filter}, {@link ng.filter:currency currency filter}, [Creating multilingual support](http://www.novanet.no/blog/hallstein-brotan/dates/2013/10/creating-multilingual-support-using-angularjs/)
* **Internationalization and Localization:** {@link guide/i18n AngularJS Guide to i18n and l10n}, {@link ng.filter:date date filter}, {@link ng.filter:currency currency filter}, [Creating multilingual support](http://www.novanet.no/blog/hallstein-brotan/dates/2013/10/creating-multilingual-support-using-angularjs/)
* **Touch events:** {@link ngTouch Touch events}
* **Accessibility:** {@link guide/accessibility ngAria}
@@ -58,7 +58,7 @@ In Angular applications, you move the job of filling page templates with data fr
We have set up a guide to many resources provided by the community, where you can find lots
of additional information and material on these topics, a list of complimentary libraries, and much more.
* {@link guide/external-resources External Angular 1 resources}
* {@link guide/external-resources External AngularJS resources}
## Getting Help
@@ -66,27 +66,27 @@ of additional information and material on these topics, a list of complimentary
The recipe for getting help on your unique issue is to create an example that could work (even if it doesn't) in a shareable example on [Plunker](http://plnkr.co/), [JSFiddle](http://jsfiddle.net/), or similar site and then post to one of the following:
* [Stackoverflow.com](http://stackoverflow.com/search?q=angularjs)
* [Angular 1 mailing list](https://groups.google.com/forum/#!forum/angular)
* [Angular 1 IRC channel](http://webchat.freenode.net/?channels=angularjs&uio=d4)
* [AngularJS mailing list](https://groups.google.com/forum/#!forum/angular)
* [AngularJS IRC channel](http://webchat.freenode.net/?channels=angularjs&uio=d4)
## Official Communications
Official announcements, news and releases are posted to our blog, G+ and Twitter:
* [Angular Blog](http://blog.angularjs.org/)
* [AngularJS Blog](http://blog.angularjs.org/)
* [Google+](https://plus.google.com/u/0/+AngularJS)
* [Twitter](https://twitter.com/angularjs)
* [Angular on YouTube](http://youtube.com/angularjs)
* [AngularJS on YouTube](http://youtube.com/angularjs)
## Contributing to Angular 1
## Contributing to AngularJS
Though we have a core group of core contributors at Google, Angular is an open source project with hundreds of contributors.
We'd love you to be one of them. When you're ready, please read the {@link misc/contribute Guide for contributing to Angular}.
Though we have a core group of core contributors at Google, AngularJS is an open source project with hundreds of contributors.
We'd love you to be one of them. When you're ready, please read the {@link misc/contribute Guide for contributing to AngularJS}.
## Something Missing?
Didn't find what you're looking for here? Check out the {@link guide/external-resources External Angular 1 resources guide}.
Didn't find what you're looking for here? Check out the {@link guide/external-resources External AngularJS resources guide}.
If you have awesome Angular 1 resources that belong on that page, please tell us about them on
If you have awesome AngularJS resources that belong on that page, please tell us about them on
[Google+](https://plus.google.com/u/0/+AngularJS) or [Twitter](https://twitter.com/angularjs).
+6 -6
View File
@@ -5,7 +5,7 @@
# Interpolation and data-binding
Interpolation markup with embedded {@link guide/expression expressions} is used by Angular to
Interpolation markup with embedded {@link guide/expression expressions} is used by AngularJS to
provide data-binding to text nodes and attribute values.
An example of interpolation is shown below:
@@ -40,7 +40,7 @@ a custom `toString()` function on the object, and uses that. Custom means that
Attributes such as `disabled` are called `boolean` attributes, because their presence means `true` and
their absence means `false`. We cannot use normal attribute bindings with them, because the HTML
specification does not require browsers to preserve the values of boolean attributes. This means that
if we put an Angular interpolation expression into such an attribute then the binding information
if we put an AngularJS interpolation expression into such an attribute then the binding information
would be lost, because the browser ignores the attribute value.
In the following example, the interpolation information would be ignored and the browser would simply
@@ -51,7 +51,7 @@ interpret the attribute as present, meaning that the button would always be disa
<button disabled="{{isDisabled}}">Disabled</button>
```
For this reason, Angular provides special `ng`-prefixed directives for the following boolean attributes:
For this reason, AngularJS provides special `ng`-prefixed directives for the following boolean attributes:
{@link ngDisabled `disabled`}, {@link ngRequired `required`}, {@link ngSelected `selected`},
{@link ngChecked `checked`}, {@link ngReadonly `readOnly`} , and {@link ngOpen `open`}.
@@ -75,7 +75,7 @@ For example, considering this template:
</svg>
```
We would expect Angular to be able to bind to this, but when we check the console we see
We would expect AngularJS to be able to bind to this, but when we check the console we see
something like `Error: Invalid value for attribute cx="{{cx}}"`. Because of the SVG DOM API's
restrictions, you cannot simply write `cx="{{cx}}"`.
@@ -131,7 +131,7 @@ directive that changes the content of that attribute, such as `ngStyle`.
### Embedding interpolation markup inside expressions
<div class="alert alert-danger">
**Note:** Angular directive attributes take either expressions *or* interpolation markup with embedded expressions.
**Note:** AngularJS directive attributes take either expressions *or* interpolation markup with embedded expressions.
It is considered **bad practice** to embed interpolation markup inside an expression:
</div>
@@ -165,4 +165,4 @@ If another directive accesses attribute data before interpolation has run, it wi
interpolation markup and not data.
- It impacts performance, as interpolation adds another watcher to the scope.
- Since this is not recommended usage, we do not test for this, and changes to
Angular core may break your code.
AngularJS core may break your code.
+21 -21
View File
@@ -4,15 +4,15 @@
@description
# What Is Angular?
# What Is AngularJS?
AngularJS is a structural framework for dynamic web apps. It lets you use HTML as your template
language and lets you extend HTML's syntax to express your application's components clearly and
succinctly. Angular's data binding and dependency injection eliminate much of the code you
succinctly. AngularJS's data binding and dependency injection eliminate much of the code you
would otherwise have to write. And it all happens within the browser, making it
an ideal partner with any server technology.
Angular is what HTML would have been, had it been designed for applications. HTML is a great
AngularJS is what HTML would have been, had it been designed for applications. HTML is a great
declarative language for static documents. It does not contain much in the way of creating
applications, and as a result building web applications is an exercise in *what do I have to do
to trick the browser into doing what I want?*
@@ -26,8 +26,8 @@ The impedance mismatch between dynamic applications and static documents is ofte
app specific. E.g., `durandal`, `ember`, etc.
Angular takes another approach. It attempts to minimize the impedance mismatch between document
centric HTML and what an application needs by creating new HTML constructs. Angular teaches the
AngularJS takes another approach. It attempts to minimize the impedance mismatch between document
centric HTML and what an application needs by creating new HTML constructs. AngularJS teaches the
browser new syntax through a construct we call *directives*. Examples include:
* Data binding, as in `{{}}`.
@@ -40,11 +40,11 @@ browser new syntax through a construct we call *directives*. Examples include:
## A complete client-side solution
Angular is not a single piece in the overall puzzle of building the client-side of a web
AngularJS is not a single piece in the overall puzzle of building the client-side of a web
application. It handles all of the DOM and AJAX glue code you once wrote by hand and puts it in a
well-defined structure. This makes Angular opinionated about how a CRUD (Create, Read, Update, Delete)
application should be built. But while it is opinionated, it also tries to make sure that its opinion
is just a starting point you can easily change. Angular comes with the following out-of-the-box:
well-defined structure. This makes AngularJS opinionated about how a CRUD (Create, Read, Update, Delete)
application should be built. But while it is opinionated, it also tries to make sure that its opinion
is just a starting point you can easily change. AngularJS comes with the following out-of-the-box:
* Everything you need to build a CRUD app in a cohesive set: Data-binding, basic templating
directives, form validation, routing, deep-linking, reusable components and dependency injection.
@@ -52,21 +52,21 @@ is just a starting point you can easily change. Angular comes with the following
* Seed application with directory layout and test scripts as a starting point.
## Angular's sweet spot
## AngularJS's sweet spot
Angular simplifies application development by presenting a higher level of abstraction to the
AngularJS simplifies application development by presenting a higher level of abstraction to the
developer. Like any abstraction, it comes at a cost of flexibility. In other words, not every app
is a good fit for Angular. Angular was built with the CRUD application in mind. Luckily CRUD
applications represent the majority of web applications. To understand what Angular is
good at, though, it helps to understand when an app is not a good fit for Angular.
is a good fit for AngularJS. AngularJS was built with the CRUD application in mind. Luckily CRUD
applications represent the majority of web applications. To understand what AngularJS is
good at, though, it helps to understand when an app is not a good fit for AngularJS.
Games and GUI editors are examples of applications with intensive and tricky DOM manipulation.
These kinds of apps are different from CRUD apps, and as a result are probably not a good fit for Angular.
These kinds of apps are different from CRUD apps, and as a result are probably not a good fit for AngularJS.
In these cases it may be better to use a library with a lower level of abstraction, such as `jQuery`.
# The Zen of Angular
## The Zen of AngularJS
Angular is built around the belief that declarative code is better than imperative when it comes
AngularJS is built around the belief that declarative code is better than imperative when it comes
to building UIs and wiring software components together, while imperative code is excellent for
expressing business logic.
@@ -83,7 +83,7 @@ expressing business logic.
Angular frees you from the following pains:
AngularJS frees you from the following pains:
* **Registering callbacks:** Registering callbacks clutters your code, making it hard to see the
forest for the trees. Removing common boilerplate code such as callbacks is a good thing. It
@@ -92,16 +92,16 @@ Angular frees you from the following pains:
* **Manipulating HTML DOM programmatically:** Manipulating HTML DOM is a cornerstone of AJAX
applications, but it's cumbersome and error-prone. By declaratively describing how the UI
should change as your application state changes, you are freed from low-level DOM manipulation
tasks. Most applications written with Angular never have to programmatically manipulate the
tasks. Most applications written with AngularJS never have to programmatically manipulate the
DOM, although you can if you want to.
* **Marshaling data to and from the UI:** CRUD operations make up the majority of AJAX
applications' tasks. The flow of marshaling data from the server to an internal object to an HTML
form, allowing users to modify the form, validating the form, displaying validation errors,
returning to an internal model, and then back to the server, creates a lot of boilerplate
code. Angular eliminates almost all of this boilerplate, leaving code that describes the
code. AngularJS eliminates almost all of this boilerplate, leaving code that describes the
overall flow of the application rather than all of the implementation details.
* **Writing tons of initialization code just to get started:** Typically you need to write a lot
of plumbing just to get a basic "Hello World" AJAX app working. With Angular you can bootstrap
of plumbing just to get a basic "Hello World" AJAX app working. With AngularJS you can bootstrap
your app easily using services, which are auto-injected into your application in a
[Guice](https://github.com/google/guice)-like dependency-injection style. This allows you
to get started developing features quickly. As a bonus, you get full control over the
+38 -37
View File
@@ -17,7 +17,7 @@ which drives many of these changes.
## Migrating from 1.5 to 1.6
Angular 1.6 fixes numerous bugs and adds new features, both in core and in external modules.
AngularJS 1.6 fixes numerous bugs and adds new features, both in core and in external modules.
In addition, it includes several security and performance improvements in commonly used services,
such as `$compile`, `$injector`, `$parse`, `$animate`, and directives, such as `input`, `ngModel`
and `select`.
@@ -587,7 +587,7 @@ HTTP requests now update the outstanding request count synchronously. Previously
would not have been updated until the request to the server was actually in flight. Now the request
count is updated before any async interceptor is called.
The new behavior will also allow end-2-end tests to more correctly detect when Angular is stable,
The new behavior will also allow end-2-end tests to more correctly detect when AngularJS is stable,
but there is a chance it may change the observed behaviour in cases where an async request
interceptor is being used.
@@ -800,11 +800,11 @@ elem.data('foo-bar'); // 2
<major />
**Due to [73050c](https://github.com/angular/angular.js/commit/73050cdda04675bfa6705dc841ddbbb6919eb048)**,
the way jqLite camelCases keys passed to `.css()` is aligned with jQuery. Previously, when using
Angular without jQuery, `.css()` would camelCase keys more aggressively. Now, only a single hyphen
AngularJS without jQuery, `.css()` would camelCase keys more aggressively. Now, only a single hyphen
followed by a lowercase letter is getting transformed. This change also affects other APIs that rely
on the `.css()` method, such as `ngStyle`.
If you are using Angular with jQuery, your application is not affected by this change. If you are
If you are using AngularJS with jQuery, your application is not affected by this change. If you are
not using jQuery, then you need to update your code as shown in the following examples:
Before:
@@ -864,7 +864,7 @@ var bgColor = elem.css('backgroundColor');
getting/setting boolean attributes will no longer take the corresponding properties into account.
Previously, all boolean attributes were reflected into the corresponding property when calling a
setter and from the corresponding property when calling a getter, even on elements that don't treat
those attributes in a special way. Now Angular doesn't do it by itself, but relies on browsers to
those attributes in a special way. Now AngularJS doesn't do it by itself, but relies on browsers to
know when to reflect the property. Note that this browser-level conversion differs between browsers;
if you need to dynamically change the state of an element, you should modify the property, not the
attribute. See https://jquery.com/upgrade-guide/1.9/#attr-versus-prop- for a more detailed
@@ -1213,10 +1213,10 @@ the `$route` service will no longer instantiate controllers nor call `resolve` o
## Migrating from 1.4 to 1.5
Angular 1.5 takes a big step towards preparing developers for a smoother transition to Angular 2 in
AngularJS 1.5 takes a big step towards preparing developers for a smoother transition to Angular in
the future. Architecting your applications using components, multi-slot transclusion, one-way
bindings in isolate scopes, using lifecycle hooks in directive controllers and relying on native ES6
features (such as classes and arrow functions) are now all possible with Angular 1.5.
features (such as classes and arrow functions) are now all possible with AngularJS 1.5.
This release includes numerous bug and security fixes, as well as performance improvements to core
@@ -1228,7 +1228,7 @@ New features have been added to more than a dozen services, directives and filte
Among them, a few stand out:
* `angular.component()`: Introducing "components", a special sort of directive that are easy to
configure and promote best practices (plus can bring Angular 1 applications closer to Angular 2's
configure and promote best practices (plus can bring AngularJS applications closer to Angular's
style of architecture).
* Multi-slot transclusion: Enabling the design of more powerful and complex UI elements with a much
simpler configuration and reduced boilerplate.
@@ -1406,7 +1406,7 @@ angular.module('myApp').config(function($touchProvider) {
```
Going forward, we recommend using [FastClick](https://github.com/ftlabs/fastclick) or perhaps one of
the [Angular 3rd party touch-related modules](http://ngmodules.org/tags/touch) that provide similar
the [AngularJS 3rd party touch-related modules](http://ngmodules.org/tags/touch) that provide similar
functionality.
Also note that modern browsers already remove the 300ms delay under some circumstances:
@@ -1431,7 +1431,8 @@ For more info on the topic, you can take a look at this
## Migrating from 1.3 to 1.4
AngularJS 1.4 fixes major animation issues and introduces a new API for `ngCookies`. Further, there
are changes to `ngMessages`, `$compile`, `ngRepeat`, `ngOptions`, `ngPattern`, `pattern` and some fixes to core filters: `limitTo` and `filter`.
are changes to `ngMessages`, `$compile`, `ngRepeat`, `ngOptions`, `ngPattern`, `pattern`, and
some fixes to core filters: `limitTo` and `filter`.
The reason for the ngAnimate refactor was to fix timing issues and to expose new APIs to allow
for developers to construct more versatile animations. We now have access to `$animateCss`
@@ -1465,7 +1466,7 @@ possibilities, can be achieved by injecting `$animateCss` into a
JavaScript-defined animation and creating custom CSS-based animations
from there.
By using `$animateCss` inside of a JavaScript animation in Angular 1.4, we can trigger custom CSS-based animations
By using `$animateCss` inside of a JavaScript animation in AngularJS 1.4, we can trigger custom CSS-based animations
directly from our JavaScript code.
```js
@@ -1634,7 +1635,7 @@ the `select` directive will now use strict comparison of the `ngModel` scope val
values to determine which option is selected. This means non-string scope values (such as `Number` or `Boolean`)
will not be matched against equivalent option strings (such as the strings `"123"`, `"true"` or `"false"`).
In Angular 1.3.x, setting `scope.x = 200` would select the option with the value 200 in the following `select`:
In AngularJS 1.3.x, setting `scope.x = 200` would select the option with the value 200 in the following `select`:
```
<select ng-model="x">
@@ -1643,7 +1644,7 @@ In Angular 1.3.x, setting `scope.x = 200` would select the option with the value
</select>
```
In Angular 1.4.x, the 'unknown option' will be selected.
In AngularJS 1.4.x, the 'unknown option' will be selected.
To remedy this, you can initialize the model as a string: `scope.x = '200'`, or if you want to
keep the model as a `Number`, you can do the conversion via `$formatters` and `$parsers` on `ngModel`:
@@ -1736,11 +1737,11 @@ the built-in pattern validator:
Due to [94533e57](https://github.com/angular/angular.js/commit/94533e570673e6b2eb92073955541fa289aabe02),
the `name` attribute of `form` elements can now only contain characters that can be evaluated as part
of an Angular expression. This is because Angular uses the value of `name` as an assignable expression
of an AngularJS expression. This is because AngularJS uses the value of `name` as an assignable expression
to set the form on the `$scope`. For example, `name="myForm"` assigns the form to `$scope.myForm` and
`name="myObj.myForm"` assigns it to `$scope.myObj.myForm`.
Previously, it was possible to also use names such `name="my:name"`, because Angular used a special setter
Previously, it was possible to also use names such `name="my:name"`, because AngularJS used a special setter
function for the form name. Now the general, more robust `$parse` setter is used.
The easiest way to migrate your code is therefore to remove all special characters from the `name` attribute.
@@ -1968,30 +1969,30 @@ angular.module('myModule').config(['$controllerProvider', function($controllerPr
}]);
```
### Angular Expression Parsing (`$parse` + `$interpolate`)
### AngularJS Expression Parsing (`$parse` + `$interpolate`)
- due to [77ada4c8](https://github.com/angular/angular.js/commit/77ada4c82d6b8fc6d977c26f3cdb48c2f5fbe5a5),
You can no longer invoke .bind, .call or .apply on a function in angular expressions.
You can no longer invoke .bind, .call or .apply on a function in AngularJS expressions.
This is to disallow changing the behaviour of existing functions
in an unforeseen fashion.
- due to [6081f207](https://github.com/angular/angular.js/commit/6081f20769e64a800ee8075c168412b21f026d99),
The (deprecated) __proto__ property does not work inside angular expressions
The (deprecated) __proto__ property does not work inside AngularJS expressions
anymore.
- due to [48fa3aad](https://github.com/angular/angular.js/commit/48fa3aadd546036c7e69f71046f659ab1de244c6),
This prevents the use of __{define,lookup}{Getter,Setter}__ inside angular
This prevents the use of __{define,lookup}{Getter,Setter}__ inside AngularJS
expressions. If you really need them for some reason, please wrap/bind them to make them
less dangerous, then make them available through the scope object.
- due to [528be29d](https://github.com/angular/angular.js/commit/528be29d1662122a34e204dd607e1c0bd9c16bbc),
This prevents the use of `Object` inside angular expressions.
This prevents the use of `Object` inside AngularJS expressions.
If you need Object.keys, make it accessible in the scope.
@@ -2026,7 +2027,7 @@ expression parser; there are six of them: false, null, undefined, NaN, 0 and "".
### Miscellaneous Angular helpers
### Miscellaneous AngularJS helpers
- **Angular.copy:** due to [b59b04f9](https://github.com/angular/angular.js/commit/b59b04f98a0b59eead53f6a53391ce1bbcbe9b57),
@@ -2074,13 +2075,13 @@ jQuery. We don't expect that app code actually depends on this accidental featur
- **jqLite:** due to [d71dbb1a](https://github.com/angular/angular.js/commit/d71dbb1ae50f174680533492ce4c7db3ff74df00),
the jQuery `detach()` method does not trigger the `$destroy` event.
If you want to destroy Angular data attached to the element, use `remove()`.
If you want to destroy AngularJS data attached to the element, use `remove()`.
### Angular HTML Compiler (`$compile`)
### AngularJS HTML Compiler (`$compile`)
- due to [2ee29c5d](https://github.com/angular/angular.js/commit/2ee29c5da81ffacdc1cabb438f5d125d5e116cb9),
@@ -2108,7 +2109,7 @@ to request both an isolate and a non-isolate scope and fix your code.
- due to [eec6394a](https://github.com/angular/angular.js/commit/eec6394a342fb92fba5270eee11c83f1d895e9fb), The `replace` flag for defining directives that
replace the element that they are on will be removed in the next major angular version.
replace the element that they are on will be removed in the next major AngularJS version.
This feature has difficult semantics (e.g. how attributes are merged) and leads to more
problems compared to what it solves. Also, with Web Components it is normal to have
custom elements in the DOM.
@@ -2331,7 +2332,7 @@ More details on the new interceptors API (which has been around as of v1.1.4) ca
- **$httpBackend:** due to [6680b7b9](https://github.com/angular/angular.js/commit/6680b7b97c0326a80bdccaf0a35031e4af641e0e), the JSONP behavior for erroneous and empty responses changed:
Previously, a JSONP response was regarded as erroneous if it was empty. Now Angular is listening to the
Previously, a JSONP response was regarded as erroneous if it was empty. Now AngularJS is listening to the
correct events to detect errors, i.e. even empty responses can be successful.
@@ -2625,7 +2626,7 @@ See [04cebcc1](https://github.com/angular/angular.js/commit/04cebcc133c8b433a3ac
With the exception of `<a>` and `<img>` elements, you cannot bind more than one expression to the
`src` or `action` attribute of elements.
This is one of several improvements to security introduces by Angular 1.2.
This is one of several improvements to security introduces by AngularJS 1.2.
Concatenating expressions makes it hard to understand whether some combination of concatenated
values are unsafe to use and potentially subject to XSS vulnerabilities. To simplify the task of
@@ -2700,7 +2701,7 @@ See [38deedd6](https://github.com/angular/angular.js/commit/38deedd6e3d806eb8262
DOM event handlers execute arbitrary JavaScript code. Using an interpolation for such handlers
means that the interpolated value is a JS string that is evaluated. Storing or generating such
strings is error prone and leads to XSS vulnerabilities. On the other hand, `ngClick` and other
Angular specific event handlers evaluate Angular expressions in non-window (Scope) context which
AngularJS specific event handlers evaluate AngularJS expressions in non-window (Scope) context which
makes them much safer.
To migrate the code follow the example below:
@@ -3027,7 +3028,7 @@ See [1adf29af](https://github.com/angular/angular.js/commit/1adf29af13890d612868
### Isolate scope only exposed to directives with `scope` property
If you declare a scope option on a directive, that directive will have an
[isolate scope](https://github.com/angular/angular.js/wiki/Understanding-Scopes). In Angular 1.0, if a
[isolate scope](https://github.com/angular/angular.js/wiki/Understanding-Scopes). In AngularJS 1.0, if a
directive with an isolate scope is used on an element, all directives on that same element have access
to the same isolate scope. For example, say we have the following directives:
@@ -3058,12 +3059,12 @@ Now what happens if we use both directives on the same element?
<div isolate-scope non-isolate-scope></div>
```
In Angular 1.0, the nonIsolateScope directive will have access to the isolateScope directives scope. The
log statements will print the same id, because the scope is the same. But in Angular 1.2, the nonIsolateScope
In AngularJS 1.0, the nonIsolateScope directive will have access to the isolateScope directives scope. The
log statements will print the same id, because the scope is the same. But in AngularJS 1.2, the nonIsolateScope
will not use the same scope as isolateScope. Instead, it will inherit the parent scope. The log statements
will print different ids.
If your code depends on the Angular 1.0 behavior (non-isolate directive needs to access state
If your code depends on the AngularJS 1.0 behavior (non-isolate directive needs to access state
from within the isolate scope), change the isolate directive to use scope locals to pass these explicitly:
**Before**
@@ -3118,13 +3119,13 @@ See [79223eae](https://github.com/angular/angular.js/commit/79223eae502283889334
This change introduces the notion of "private" properties (properties
whose names begin and/or end with an underscore) on the scope chain.
These properties will not be available to Angular expressions (i.e. {{
These properties will not be available to AngularJS expressions (i.e. {{
}} interpolation in templates and strings passed to `$parse`) They are
freely available to JavaScript code (as before).
**Motivation**
Angular expressions execute in a limited context. They do not have
AngularJS expressions execute in a limited context. They do not have
direct access to the global scope, `window`, `document` or the Function
constructor. However, they have direct access to names/properties on
the scope chain. It has been a long standing best practice to keep
@@ -3133,17 +3134,17 @@ controller.) That's easier said than done for two reasons:
1. JavaScript does not have a notion of private properties so if you need
someone on the scope chain for JavaScript use, you also expose it to
Angular expressions
AngularJS expressions
2. The new `controller as` syntax that's now in increased usage exposes the
entire controller on the scope chain greatly increasing the exposed surface.
Though Angular expressions are written and controlled by the developer, they:
Though AngularJS expressions are written and controlled by the developer, they:
1. Typically deal with user input
2. Don't get the kind of test coverage that JavaScript code would
This commit provides a way, via a naming convention, to allow restricting properties from
controllers/scopes. This means Angular expressions can access only those properties that
controllers/scopes. This means AngularJS expressions can access only those properties that
are actually needed by the expressions.
See [3d6a89e8](https://github.com/angular/angular.js/commit/3d6a89e8888b14ae5cb5640464e12b7811853c7e).
@@ -3162,7 +3163,7 @@ See [d87fa004](https://github.com/angular/angular.js/commit/d87fa0042375b025b98c
### Uncommon region-specific local files were removed from i18n
AngularJS uses the Google Closure library's locale files. The following locales were removed from
Closure, so Angular is not able to continue to support them:
Closure, so AngularJS is not able to continue to support them:
`chr`, `cy`, `el-polyton`, `en-zz`, `fr-rw`, `fr-sn`, `fr-td`, `fr-tg`, `haw`, `it-ch`, `ln-cg`,
`mo`, `ms-bn`, `nl-aw`, `nl-be`, `pt-ao`, `pt-gw`, `pt-mz`, `pt-st`, `ro-md`, `ru-md`, `ru-ua`,
+49 -53
View File
@@ -3,17 +3,19 @@
@sortOrder 320
@description
# What is a Module?
# Modules
## What is a Module?
You can think of a module as a container for the different parts of your app controllers,
services, filters, directives, etc.
# Why?
## Why?
Most applications have a main method that instantiates and wires together the different parts of
the application.
Angular apps don't have a main method. Instead modules declaratively specify how an application
AngularJS apps don't have a main method. Instead modules declaratively specify how an application
should be bootstrapped. There are several advantages to this approach:
* The declarative process is easier to understand.
@@ -23,7 +25,7 @@ should be bootstrapped. There are several advantages to this approach:
* End-to-end tests can use modules to override configuration.
# The Basics
## The Basics
I'm in a hurry. How do I get a Hello World module working?
@@ -65,7 +67,7 @@ Important things to notice:
This array is the list of modules `myApp` depends on.
# Recommended Setup
## Recommended Setup
While the example above is simple, it will not scale to large applications. Instead we recommend
that you break your application to multiple modules like this:
@@ -136,39 +138,46 @@ The above is a suggestion. Tailor it to your needs.
# Module Loading & Dependencies
## Module Loading
A module is a collection of configuration and run blocks which get applied to the application
during the bootstrap process. In its simplest form the module consists of a collection of two kinds
of blocks:
A {@link angular.Module module} is a collection of providers, services, directives etc.,
and optionally config and run blocks which get applied to the application during the
bootstrap process.
1. **Configuration blocks** - get executed during the provider registrations and configuration
phase. Only providers and constants can be injected into configuration blocks. This is to
prevent accidental instantiation of services before they have been fully configured.
2. **Run blocks** - get executed after the injector is created and are used to kickstart the
application. Only instances and constants can be injected into run blocks. This is to prevent
further system configuration during application run time.
The {@link angular.Module module API} describes all the available methods and how they can be used.
```js
angular.module('myModule', []).
config(function(injectables) { // provider-injector
// This is an example of config block.
// You can have as many of these as you want.
// You can only inject Providers (not instances)
// into config blocks.
}).
run(function(injectables) { // instance-injector
// This is an example of a run block.
// You can have as many of these as you want.
// You can only inject instances (not Providers)
// into run blocks
});
```
See {@link guide/di#using-dependency-injection Using Dependency Injection} to find out which
dependencies can be injected in each method.
## Configuration Blocks
### Dependencies and Order of execution
Modules can list other modules as their dependencies. Depending on a module implies that the required
module will be loaded before the requiring module is loaded.
In a single module the order of execution is as follows:
1. {@link angular.Module#provider provider} functions are executed, so they and the services they
define can be made available to the {@link auto.$injector $injector}.
2. After that, the configuration blocks ({@link angular.Module#config config} functions) are executed.
This means the configuration blocks of the required modules execute before the configuration blocks
of any requiring module.
This continues until all module dependencies has been resolved.
Then, the {@link angular.Module#run run} blocks that have been collected from each module are
executed in order of requirement.
Note: each module is only loaded once, even if multiple other modules require it.
Note: the factory function for "values" and "services" is called lazily when the value/service is
injected for the first time.
### Registration in the config block
While it is recommended to register injectables directly with the {@link angular.Module module API},
it is also possible to register services, directives etc. by injecting
{@link $provide $provide} or the individual service providers into the config function:
There are some convenience methods on the module which are equivalent to the `config` block. For
example:
```js
angular.module('myModule', []).
@@ -188,35 +197,22 @@ angular.module('myModule', []).
});
```
<div class="alert alert-info">
When bootstrapping, first Angular applies all constant definitions.
Then Angular applies configuration blocks in the same order they were registered.
</div>
### Run Blocks
## Run Blocks
Run blocks are the closest thing in Angular to the main method. A run block is the code which
Run blocks are the closest thing in AngularJS to the main method. A run block is the code which
needs to run to kickstart the application. It is executed after all of the services have been
configured and the injector has been created. Run blocks typically contain code which is hard
to unit-test, and for this reason should be declared in isolated modules, so that they can be
ignored in the unit-tests.
## Dependencies
Modules can list other modules as their dependencies. Depending on a module implies that the required
module needs to be loaded before the requiring module is loaded. In other words the configuration
blocks of the required modules execute before the configuration blocks of the requiring module.
The same is true for the run blocks. Each module can only be loaded once, even if multiple other
modules require it.
## Asynchronous Loading
### Asynchronous Loading
Modules are a way of managing $injector configuration, and have nothing to do with loading of
scripts into a VM. There are existing projects which deal with script loading, which may be used
with Angular. Because modules do nothing at load time they can be loaded into the VM in any order
with AngularJS. Because modules do nothing at load time they can be loaded into the VM in any order
and thus script loaders can take advantage of this property and parallelize the loading process.
## Creation versus Retrieval
### Creation versus Retrieval
Beware that using `angular.module('myModule', [])` will create the module `myModule` and overwrite any
existing module named `myModule`. Use `angular.module('myModule')` to retrieve an existing module.
@@ -235,14 +231,14 @@ var myModule = angular.module('myModule', []);
var myModule = angular.module('myOtherModule');
```
# Unit Testing
## Unit Testing
A unit test is a way of instantiating a subset of an application to apply stimulus to it.
Small, structured modules help keep unit tests concise and focused.
<div class="did you know...">
Each module can only be loaded once per injector.
Usually an Angular app has only one injector and modules are only loaded once.
Usually an AngularJS app has only one injector and modules are only loaded once.
Each test has its own injector and modules are loaded multiple times.
</div>
+2 -2
View File
@@ -81,13 +81,13 @@ For more information, see the
## Disable comment and css class directives
By default AngularJS compiles and executes all directives inside comments and element classes.
In order to perform this task, angular compiler must look for directives by:
In order to perform this task, the AngularJS compiler must look for directives by:
- Parse all your application element classes.
- Parse all your application html comments.
Nowadays most of the Angular projects are using only element and attribute directives,
Nowadays most of the AngularJS projects are using only element and attribute directives,
and in such projects there is no need to compile comments and classes.
If you are sure that your project only uses element and attribute directives,
+11 -11
View File
@@ -6,7 +6,7 @@
# Providers
Each web application you build is composed of objects that collaborate to get stuff done. These
objects need to be instantiated and wired together for the app to work. In Angular apps most of
objects need to be instantiated and wired together for the app to work. In AngularJS apps most of
these objects are instantiated and wired together automatically by the {@link auto.$injector
injector service}.
@@ -14,7 +14,7 @@ The injector creates two types of objects, **services** and **specialized object
Services are objects whose API is defined by the developer writing the service.
Specialized objects conform to a specific Angular framework API. These objects are one of
Specialized objects conform to a specific AngularJS framework API. These objects are one of
controllers, directives, filters or animations.
The injector needs to know how to create these objects. You tell it by registering a "recipe" for
@@ -35,11 +35,11 @@ In order for the injector to know how to create and wire together all of these o
a registry of "recipes". Each recipe has an identifier of the object and the description of how to
create this object.
Each recipe belongs to an {@link angular.Module Angular module}. An Angular module is a bag
Each recipe belongs to an {@link angular.Module AngularJS module}. An AngularJS module is a bag
that holds one or more recipes. And since manually keeping track of module dependencies is no fun,
a module can contain information about dependencies on other modules as well.
When an Angular application starts with a given application module, Angular creates a new instance
When an AngularJS application starts with a given application module, AngularJS creates a new instance
of injector, which in turn creates a registry of recipes as a union of all recipes defined in the
core "ng" module, application module and its dependencies. The injector then consults the recipe
registry when it needs to create an object for your application.
@@ -55,10 +55,10 @@ var myApp = angular.module('myApp', []);
myApp.value('clientId', 'a12345654321x');
```
Notice how we created an Angular module called `myApp`, and specified that this module definition
Notice how we created an AngularJS module called `myApp`, and specified that this module definition
contains a "recipe" for constructing the `clientId` service, which is a simple string in this case.
And this is how you would display it via Angular's data-binding:
And this is how you would display it via AngularJS's data-binding:
```javascript
@@ -95,7 +95,7 @@ The Factory recipe constructs a new service using a function with zero or more a
are dependencies on other services). The return value of this function is the service instance
created by this recipe.
Note: All services in Angular are singletons. That means that the injector uses each recipe at most
Note: All services in AngularJS are singletons. That means that the injector uses each recipe at most
once to create the object. The injector then caches the reference for all future needs.
Since a Factory is a more powerful version of the Value recipe, the same service can be constructed with it.
@@ -246,7 +246,7 @@ Notice that the unicorn provider is injected into the config function. This inje
provider injector which is different from the regular instance injector, in that it instantiates
and wires (injects) all provider instances only.
During application bootstrap, before Angular goes off creating all services, it configures and
During application bootstrap, before AngularJS goes off creating all services, it configures and
instantiates all providers. We call this the configuration phase of the application life-cycle.
During this phase, services aren't accessible because they haven't been created yet.
@@ -256,7 +256,7 @@ creating services starts. We call this part of the application life-cycle the ru
## Constant Recipe
We've just learned how Angular splits the life-cycle into configuration phase and run phase and how
We've just learned how AngularJS splits the life-cycle into configuration phase and run phase and how
you can provide configuration to your application via the config function. Since the config
function runs in the configuration phase when no services are available, it doesn't have access
even to simple value objects created via the Value recipe.
@@ -308,7 +308,7 @@ myApp.controller('DemoController', ["clientId", "planetName", function DemoContr
Earlier we mentioned that we also have special purpose objects that are different from services.
These objects extend the framework as plugins and therefore must implement interfaces specified by
Angular. These interfaces are Controller, Directive, Filter and Animation.
AngularJS. These interfaces are Controller, Directive, Filter and Animation.
The instructions for the injector to create these special objects (with the exception of the
Controller objects) use the Factory recipe behind the scenes.
@@ -340,7 +340,7 @@ We can then use the component like this:
</html>
```
Using Factory recipes, you can also define Angular's filters and animations, but the controllers
Using Factory recipes, you can also define AngularJS's filters and animations, but the controllers
are a bit special. You create a controller as a custom type that declares its dependencies as
arguments for its constructor function. This constructor is then registered with a module. Let's
take a look at the `DemoController`, created in one of the early examples:
+28 -28
View File
@@ -16,8 +16,8 @@ watch {@link guide/expression expressions} and propagate events.
model mutations.
- Scopes provide APIs ({@link ng.$rootScope.Scope#$apply $apply}) to
propagate any model changes through the system into the view from outside of the "Angular
realm" (controllers, services, Angular event handlers).
propagate any model changes through the system into the view from outside of the "AngularJS
realm" (controllers, services, AngularJS event handlers).
- Scopes can be nested to limit access to the properties of application components while providing
access to shared model properties. Nested scopes are either "child scopes" or "isolate scopes".
@@ -108,7 +108,7 @@ to test the behavior without being distracted by the rendering details.
## Scope Hierarchies
Each Angular application has exactly one {@link ng.$rootScope root scope}, but
Each AngularJS application has exactly one {@link ng.$rootScope root scope}, but
may have several child scopes.
The application can have multiple scopes, because some {@link guide/directive directives} create
@@ -116,7 +116,7 @@ new child scopes (refer to directive documentation to see which directives creat
When new scopes are created, they are added as children of their parent scope. This creates a tree
structure which parallels the DOM where they're attached.
When Angular evaluates `{{name}}`, it first looks at the scope associated with the given
When AngularJS evaluates `{{name}}`, it first looks at the scope associated with the given
element for the `name` property. If no such property is found, it searches the parent scope
and so on until the root scope is reached. In JavaScript this behavior is known as prototypical
inheritance, and child scopes prototypically inherit from their parents.
@@ -141,7 +141,7 @@ a diagram depicting the scope boundaries.
angular.module('scopeExample', [])
.controller('GreetController', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.name = 'World';
$rootScope.department = 'Angular';
$rootScope.department = 'AngularJS';
}])
.controller('ListController', ['$scope', function($scope) {
$scope.names = ['Igor', 'Misko', 'Vojta'];
@@ -158,7 +158,7 @@ a diagram depicting the scope boundaries.
<img class="center" src="img/guide/concepts-scope.png">
Notice that Angular automatically places `ng-scope` class on elements where scopes are
Notice that AngularJS automatically places `ng-scope` class on elements where scopes are
attached. The `<style>` definition in this example highlights in red the new scope locations. The
child scopes are necessary because the repeater evaluates `{{name}}` expression, but
depending on which scope the expression is evaluated it produces different result. Similarly the
@@ -173,7 +173,7 @@ purposes. (It is unlikely that one would need to retrieve scopes in this way ins
application.) The location where the root scope is attached to the DOM is defined by the location
of {@link ng.directive:ngApp `ng-app`} directive. Typically
`ng-app` is placed on the `<html>` element, but it can be placed on other elements as well, if,
for example, only a portion of the view needs to be controlled by Angular.
for example, only a portion of the view needs to be controlled by AngularJS.
To examine the scope in the debugger:
@@ -230,11 +230,11 @@ The normal flow of a browser receiving an event is that it executes a correspond
callback. Once the callback completes the browser re-renders the DOM and returns to waiting for
more events.
When the browser calls into JavaScript the code executes outside the Angular execution context,
which means that Angular is unaware of model modifications. To properly process model
modifications the execution has to enter the Angular execution context using the {@link
When the browser calls into JavaScript the code executes outside the AngularJS execution context,
which means that AngularJS is unaware of model modifications. To properly process model
modifications the execution has to enter the AngularJS execution context using the {@link
ng.$rootScope.Scope#$apply `$apply`} method. Only model modifications which
execute inside the `$apply` method will be properly accounted for by Angular. For example if a
execute inside the `$apply` method will be properly accounted for by AngularJS. For example if a
directive listens on DOM events, such as {@link
ng.directive:ngClick `ng-click`} it must evaluate the
expression inside the `$apply` method.
@@ -264,14 +264,14 @@ the `$digest` phase. This delay is desirable, since it coalesces multiple model
3. **Model mutation**
For mutations to be properly observed, you should make them only within the {@link
ng.$rootScope.Scope#$apply scope.$apply()}. Angular APIs do this
ng.$rootScope.Scope#$apply scope.$apply()}. AngularJS APIs do this
implicitly, so no extra `$apply` call is needed when doing synchronous work in controllers,
or asynchronous work with {@link ng.$http $http}, {@link ng.$timeout $timeout}
or {@link ng.$interval $interval} services.
4. **Mutation observation**
At the end of `$apply`, Angular performs a {@link ng.$rootScope.Scope#$digest
At the end of `$apply`, AngularJS performs a {@link ng.$rootScope.Scope#$digest
$digest} cycle on the root scope, which then propagates throughout all child scopes. During
the `$digest` cycle, all `$watch`ed expressions or functions are checked for model mutation
and if a mutation is detected, the `$watch` listener is called.
@@ -334,7 +334,7 @@ information.
### Scope `$watch` Performance Considerations
Dirty checking the scope for property changes is a common operation in Angular and for this reason
Dirty checking the scope for property changes is a common operation in AngularJS and for this reason
the dirty checking function must be efficient. Care should be taken that the dirty checking
function does not do any DOM access, as DOM access is orders of magnitude slower than property
access on JavaScript object.
@@ -354,7 +354,7 @@ Dirty checking can be done with three strategies: By reference, by collection co
## Integration with the browser event loop
<img class="pull-right" style="padding-left: 3em; padding-bottom: 1em;" src="img/guide/concepts-runtime.png">
The diagram and the example below describe how Angular interacts with the browser's event loop.
The diagram and the example below describe how AngularJS interacts with the browser's event loop.
1. The browser's event-loop waits for an event to arrive. An event is a user interaction, timer event,
or network event (response from a server).
@@ -363,19 +363,19 @@ The diagram and the example below describe how Angular interacts with the browse
3. Once the callback executes, the browser leaves the JavaScript context and
re-renders the view based on DOM changes.
Angular modifies the normal JavaScript flow by providing its own event processing loop. This
splits the JavaScript into classical and Angular execution context. Only operations which are
applied in the Angular execution context will benefit from Angular data-binding, exception handling,
property watching, etc... You can also use $apply() to enter the Angular execution context from JavaScript. Keep in
AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This
splits the JavaScript into classical and AngularJS execution context. Only operations which are
applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling,
property watching, etc... You can also use $apply() to enter the AngularJS execution context from JavaScript. Keep in
mind that in most places (controllers, services) $apply has already been called for you by the
directive which is handling the event. An explicit call to $apply is needed only when
implementing custom event callbacks, or when working with third-party library callbacks.
1. Enter the Angular execution context by calling {@link guide/scope scope}`.`{@link
1. Enter the AngularJS execution context by calling {@link guide/scope scope}`.`{@link
ng.$rootScope.Scope#$apply $apply}`(stimulusFn)`, where `stimulusFn` is
the work you wish to do in the Angular execution context.
2. Angular executes the `stimulusFn()`, which typically modifies application state.
3. Angular enters the {@link ng.$rootScope.Scope#$digest $digest} loop. The
the work you wish to do in the AngularJS execution context.
2. AngularJS executes the `stimulusFn()`, which typically modifies application state.
3. AngularJS enters the {@link ng.$rootScope.Scope#$digest $digest} loop. The
loop is made up of two smaller loops which process {@link
ng.$rootScope.Scope#$evalAsync $evalAsync} queue and the {@link
ng.$rootScope.Scope#$watch $watch} list. The {@link
@@ -391,8 +391,8 @@ implementing custom event callbacks, or when working with third-party library ca
5. The {@link ng.$rootScope.Scope#$watch $watch} list is a set of expressions
which may have changed since last iteration. If a change is detected then the `$watch`
function is called which typically updates the DOM with the new value.
6. Once the Angular {@link ng.$rootScope.Scope#$digest $digest} loop finishes,
the execution leaves the Angular and JavaScript context. This is followed by the browser
6. Once the AngularJS {@link ng.$rootScope.Scope#$digest $digest} loop finishes,
the execution leaves the AngularJS and JavaScript context. This is followed by the browser
re-rendering the DOM to reflect any changes.
@@ -411,12 +411,12 @@ user enters text into the text field.
2. The {@link ng.directive:input input} directive
captures the change to the input's value and calls {@link
ng.$rootScope.Scope#$apply $apply}`("name = 'X';")` to update the
application model inside the Angular execution context.
3. Angular applies the `name = 'X';` to the model.
application model inside the AngularJS execution context.
3. AngularJS applies the `name = 'X';` to the model.
4. The {@link ng.$rootScope.Scope#$digest $digest} loop begins
5. The {@link ng.$rootScope.Scope#$watch $watch} list detects a change
on the `name` property and notifies the {@link ng.$interpolate interpolation},
which in turn updates the DOM.
6. Angular exits the execution context, which in turn exits the `keydown` event and with it
6. AngularJS exits the execution context, which in turn exits the `keydown` event and with it
the JavaScript execution context.
7. The browser re-renders the view with the updated text.
+15 -15
View File
@@ -14,7 +14,7 @@ keep in mind as you build your application.
Email us at [security@angularjs.org](mailto:security@angularjs.org) to report any potential
security issues in AngularJS.
Please keep in mind the points below about Angular's expression language.
Please keep in mind the points below about AngularJS's expression language.
## Use the latest AngularJS possible
@@ -25,19 +25,19 @@ of upcoming security patches and other updates.
Be ready to update rapidly when new security-centric patches are available.
Those that stray from Angular standards (such as modifying Angular's core) may have difficulty updating,
Those that stray from AngularJS standards (such as modifying AngularJS's core) may have difficulty updating,
so keeping to AngularJS standards is not just a functionality issue, it's also critical in order to
facilitate rapid security updates.
## Angular Templates and Expressions
## AngularJS Templates and Expressions
**If an attacker has access to control Angular templates or expressions, they can exploit an Angular application
**If an attacker has access to control AngularJS templates or expressions, they can exploit an AngularJS application
via an XSS attack, regardless of the version.**
There are a number of ways that templates and expressions can be controlled:
* **Generating Angular templates on the server containing user-provided content**. This is the most common pitfall
* **Generating AngularJS templates on the server containing user-provided content**. This is the most common pitfall
where you are generating HTML via some server-side engine such as PHP, Java or ASP.NET.
* **Passing an expression generated from user-provided content in calls to the following methods on a {@link scope scope}**:
* `$watch(userContent, ...)`
@@ -55,14 +55,14 @@ There are a number of ways that templates and expressions can be controlled:
`{{ value | orderBy : userContent }}`
### Sandbox removal
Each version of Angular 1 up to, but not including 1.6, contained an expression sandbox, which reduced the surface area of
the vulnerability but never removed it. **In Angular 1.6 we removed this sandbox as developers kept relying upon it as a security
feature even though it was always possible to access arbitrary JavaScript code if one could control the Angular templates
Each version of AngularJS 1 up to, but not including 1.6, contained an expression sandbox, which reduced the surface area of
the vulnerability but never removed it. **In AngularJS 1.6 we removed this sandbox as developers kept relying upon it as a security
feature even though it was always possible to access arbitrary JavaScript code if one could control the AngularJS templates
or expressions of applications.**
Control of the Angular templates makes applications vulnerable even if there was a completely secure sandbox:
Control of the AngularJS templates makes applications vulnerable even if there was a completely secure sandbox:
* https://ryhanson.com/stealing-session-tokens-on-plunker-with-an-angular-expression-injection/ in this blog post the author shows
a (now closed) vulnerability in the Plunker application due to server-side rendering inside an Angular template.
a (now closed) vulnerability in the Plunker application due to server-side rendering inside an AngularJS template.
* https://ryhanson.com/angular-expression-injection-walkthrough/ in this blog post the author describes an attack, which does not
rely upon an expression sandbox bypass, that can be made because the sample application is rendering a template on the server that
contains user entered content.
@@ -75,9 +75,9 @@ Control of the Angular templates makes applications vulnerable even if there was
* Consider using {@link ng.directive:ngCsp CSP} (but don't rely only on CSP)
**You can use suitably sanitized server-side templating to dynamically generate CSS, URLs, etc, but not for generating templates that are
bootstrapped/compiled by Angular.**
bootstrapped/compiled by AngularJS.**
**If you must continue to allow user-provided content in an Angular template then the safest option is to ensure that it is only
**If you must continue to allow user-provided content in an AngularJS template then the safest option is to ensure that it is only
present in the part of the template that is made inert via the {@link ngNonBindable} directive.**
@@ -85,7 +85,7 @@ present in the part of the template that is made inert via the {@link ngNonBinda
Whenever your application makes requests to a server there are potential security issues that need
to be blocked. Both server and the client must cooperate in order to eliminate these threats.
Angular comes pre-configured with strategies that address these issues, but for this to work backend
AngularJS comes pre-configured with strategies that address these issues, but for this to work backend
server cooperation is required.
@@ -97,7 +97,7 @@ For more information please visit {@link $http#cross-site-request-forgery-xsrf-p
### JSON Hijacking Protection
Protection from JSON Hijacking is provided if the server prefixes all JSON requests with following string `")]}',\n"`.
Angular will automatically strip the prefix before processing it as JSON.
AngularJS will automatically strip the prefix before processing it as JSON.
For more information please visit {@link $http#json-vulnerability-protection JSON Hijacking Protection}.
Bear in mind that calling `$http.jsonp` gives the remote server (and, if the request is not secured, any Man-in-the-Middle attackers)
@@ -123,7 +123,7 @@ For more information please visit {@link $sce} and {@link ngSanitize.$sanitize}.
## Using Local Caches
There are various places that the browser can store (or cache) data. Within Angular there are objects created by
There are various places that the browser can store (or cache) data. Within AngularJS there are objects created by
the {@link $cacheFactory}. These objects, such as {@link $templateCache} are used to store and retrieve data,
primarily used by {@link $http} and the {@link script} directive to cache templates and other data.
+10 -10
View File
@@ -5,29 +5,29 @@
# Services
Angular services are substitutable objects that are wired together using {@link di dependency
AngularJS services are substitutable objects that are wired together using {@link di dependency
injection (DI)}. You can use services to organize and share code across your app.
Angular services are:
AngularJS services are:
* Lazily instantiated Angular only instantiates a service when an application component depends
* Lazily instantiated AngularJS only instantiates a service when an application component depends
on it.
* Singletons Each component dependent on a service gets a reference to the single instance
generated by the service factory.
Angular offers several useful services (like {@link ng.$http `$http`}), but for most applications
AngularJS offers several useful services (like {@link ng.$http `$http`}), but for most applications
you'll also want to {@link services#creating-services create your own}.
<div class="alert alert-info">
**Note:** Like other core Angular identifiers, built-in services always start with `$`
**Note:** Like other core AngularJS identifiers, built-in services always start with `$`
(e.g. `$http`).
</div>
## Using a Service
To use an Angular service, you add it as a dependency for the component (controller, service,
filter or directive) that depends on the service. Angular's {@link di dependency injection}
To use an AngularJS service, you add it as a dependency for the component (controller, service,
filter or directive) that depends on the service. AngularJS's {@link di dependency injection}
subsystem takes care of the rest.
<example module="myServiceModule" name="services-usage">
@@ -72,7 +72,7 @@ subsystem takes care of the rest.
## Creating Services
Application developers are free to define their own services by registering the service's name and
**service factory function**, with an Angular module.
**service factory function**, with an AngularJS module.
The **service factory function** generates the single object or function that represents the
service to the rest of the application. The object or function returned by the service is
@@ -180,7 +180,7 @@ This technique is often used in unit tests to mock out a service's dependencies.
## Unit Testing
The following is a unit test for the `notify` service from the {@link services#creating-services
Creating Angular Services} example above. The unit test example uses a Jasmine spy (mock) instead
Creating AngularJS Services} example above. The unit test example uses a Jasmine spy (mock) instead
of a real browser alert.
```js
@@ -233,5 +233,5 @@ it('should clear messages after alert', function() {
## Related API
* {@link ./api/ng/service Angular Service API}
* {@link ./api/ng/service AngularJS Service API}
* {@link angular.injector Injector API}
+6 -6
View File
@@ -5,16 +5,16 @@
# Templates
In Angular, templates are written with HTML that contains Angular-specific elements and attributes.
Angular combines the template with information from the model and controller to render the dynamic
In AngularJS, templates are written with HTML that contains AngularJS-specific elements and attributes.
AngularJS combines the template with information from the model and controller to render the dynamic
view that a user sees in the browser.
These are the types of Angular elements and attributes you can use:
These are the types of AngularJS elements and attributes you can use:
* {@link guide/directive Directive} — An attribute or element that
augments an existing DOM element or represents a reusable DOM component.
* {@link ng.$interpolate Markup} — The double curly brace notation `{{ }}` to bind expressions
to elements is built-in Angular markup.
to elements is built-in AngularJS markup.
* {@link guide/filter Filter} — Formats data for display.
* {@link forms Form controls} — Validates user input.
@@ -35,13 +35,13 @@ curly-brace {@link expression expression} bindings:
</html>
```
In a simple app, the template consists of HTML, CSS, and Angular directives contained
In a simple app, the template consists of HTML, CSS, and AngularJS directives contained
in just one HTML file (usually `index.html`).
In a more complex app, you can display multiple views within one main page using "partials"
segments of template located in separate HTML files. You can use the
{@link ngRoute.directive:ngView ngView} directive to load partials based on configuration passed
to the {@link ngRoute.$route $route} service. The {@link tutorial/ angular tutorial} shows this
to the {@link ngRoute.$route $route} service. The {@link tutorial/ AngularJS tutorial} shows this
technique in steps seven and eight.
+12 -12
View File
@@ -8,7 +8,7 @@
JavaScript is a dynamically typed language which comes with great power of expression, but it also
comes with almost no help from the compiler. For this reason we feel very strongly that any code
written in JavaScript needs to come with a strong set of tests. We have built many features into
Angular which make testing your Angular applications easy. With Angular, there is no excuse for not testing.
AngularJS which make testing your AngularJS applications easy. With AngularJS, there is no excuse for not testing.
## Separation of Concerns
@@ -25,7 +25,7 @@ typical project. The reason is that the developers often mix concerns resulting
piece of code which does everything. It makes an XHR request, it sorts the response data, and then it
manipulates the DOM.
With Angular, we try to make it easy for you to do the right thing. For your XHR requests, we
With AngularJS, we try to make it easy for you to do the right thing. For your XHR requests, we
provide dependency injection, so your requests can be simulated. For the DOM, we abstract it, so you can
test your model without having to manipulate the DOM directly. Your tests can then
assert that the data has been sorted without having to create or look at the state of the DOM or to
@@ -33,22 +33,22 @@ wait for any XHR requests to return data. The individual sort function can be te
## With great power comes great responsibility
Angular is written with testability in mind, but it still requires that you do the right thing.
AngularJS is written with testability in mind, but it still requires that you do the right thing.
We tried to make the right thing easy, but if you ignore these guidelines you may end up with an
untestable application.
## Dependency Injection
Angular comes with {@link di dependency injection} built-in, which makes testing components much
AngularJS comes with {@link di dependency injection} built-in, which makes testing components much
easier, because you can pass in a component's dependencies and stub or mock them as you wish.
Components that have their dependencies injected allow them to be easily mocked on a test by
test basis, without having to mess with any global variables that could inadvertently affect
another test.
## Additional tools for testing Angular applications
## Additional tools for testing AngularJS applications
For testing Angular applications there are certain tools that you should use that will make testing much
For testing AngularJS applications there are certain tools that you should use that will make testing much
easier to set up and run.
### Karma
@@ -65,7 +65,7 @@ are available on [the Karma website](http://karma-runner.github.io/0.12/intro/in
### Jasmine
[Jasmine](http://jasmine.github.io/1.3/introduction.html) is a behavior driven development framework for
JavaScript that has become the most popular choice for testing Angular applications. Jasmine
JavaScript that has become the most popular choice for testing AngularJS applications. Jasmine
provides functions to help with structuring your tests and also making assertions. As your tests
grow, keeping them well structured and documented is vital, and Jasmine helps achieve this.
@@ -109,15 +109,15 @@ what they are. To use Jasmine with Karma, we use the
### angular-mocks
Angular also provides the {@link ngMock} module, which provides mocking for your tests. This is used
to inject and mock Angular services within unit tests. In addition, it is able to extend other
AngularJS also provides the {@link ngMock} module, which provides mocking for your tests. This is used
to inject and mock AngularJS services within unit tests. In addition, it is able to extend other
modules so they are synchronous. Having tests synchronous keeps them much cleaner and easier to work
with. One of the most useful parts of ngMock is {@link ngMock.$httpBackend}, which lets us mock XHR
requests in tests, and return sample data instead.
## Testing a Controller
Because Angular separates logic from the view layer, it keeps controllers easy to test. Let's take a
Because AngularJS separates logic from the view layer, it keeps controllers easy to test. Let's take a
look at how we might test the controller below, which provides `$scope.grade`, which sets a property
on the scope based on the length of the password.
@@ -282,13 +282,13 @@ describe('length filter', function() {
```
## Testing Directives
Directives in angular are responsible for encapsulating complex functionality within custom HTML tags,
Directives in AngularJS are responsible for encapsulating complex functionality within custom HTML tags,
attributes, classes or comments. Unit tests are very important for directives because the components
you create with directives may be used throughout your application and in many different contexts.
### Simple HTML Element Directive
Let's start with an angular app with no dependencies.
Let's start with an AngularJS app with no dependencies.
```js
var app = angular.module('myApp', []);
+18 -18
View File
@@ -2,26 +2,26 @@
@name Downloading
@description
# Including Angular scripts from the Google CDN
# Including AngularJS scripts from the Google CDN
The quickest way to get started is to point your html `<script>` tag to a
[Google CDN](https://developers.google.com/speed/libraries/#angularjs) URL.
This way, you don't have to download anything or maintain a local copy.
There are two types of Angular script URLs you can point to, one for development and one for
There are two types of AngularJS script URLs you can point to, one for development and one for
production:
* __angular.js__ — This is the human-readable, non-minified version, suitable for web development.
* __angular.min.js__ — This is the minified version, which we strongly suggest you use in
production.
To point your code to an angular script on the Google CDN server, use the following template. This
To point your code to an AngularJS script on the Google CDN server, use the following template. This
example points to the minified version 1.5.6:
```html
<!doctype html>
<html ng-app>
<head>
<title>My Angular App</title>
<title>My AngularJS App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
</head>
<body>
@@ -32,22 +32,22 @@ example points to the minified version 1.5.6:
<div class="alert alert-info">
Note that only versions 1.0.1 and above are available on the CDN. If you need an earlier version
(which you shouldn't) you can use the https://code.angularjs.org/ URL, which was the previous
recommended location for hosted code source. If you're still using the Angular server you should
recommended location for hosted code source. If you're still using the AngularJS server you should
switch to the CDN version for even faster loading times.
</div>
<br />
# Downloading and hosting angular files locally
This option is for those who want to work with Angular offline, or those who want to host the
Angular files on their own servers.
# Downloading and hosting AngularJS files locally
This option is for those who want to work with AngularJS offline, or those who want to host the
AngularJS files on their own servers.
If you navigate to https://code.angularjs.org/, you'll see a directory listing with all of the
Angular versions since we started releasing versioned build artifacts. Each directory contains all
AngularJS versions since we started releasing versioned build artifacts. Each directory contains all
artifacts that we released for a particular version. Download the version you want and have fun.
<div class="alert alert-warning">
You can ignore directories starting with `2.` (e.g. `2.0.0-beta.17`) — they are not related to
AngularJS. They contain build artifacts from [Angular 2](https://angular.io) versions.
AngularJS. They contain build artifacts from [Angular](https://angular.io) versions.
</div>
<br />
@@ -72,10 +72,10 @@ development) come in two flavors — one suitable for development, the other for
<br />
The set of files included in each version directory are:
* __`angular.zip`__ — This is a zip archive that contains all of the files released for this Angular
* __`angular.zip`__ — This is a zip archive that contains all of the files released for this AngularJS
version. Use this file to get everything in a single download.
* __`angular.js`__ — The core Angular framework. This is all you need to get your Angular app
* __`angular.js`__ — The core AngularJS framework. This is all you need to get your AngularJS app
running.
* __`angular-csp.css`__ — You only need this file if you are using
@@ -86,14 +86,14 @@ The set of files included in each version directory are:
apps even easier. Your unit/integration test harness should load this file after `angular.js` is
loaded.
* __`angular-loader.js`__ — Module loader for Angular modules. If you are loading multiple
script files containing Angular modules, you can load them asynchronously and in any order as long
* __`angular-loader.js`__ — Module loader for AngularJS modules. If you are loading multiple
script files containing AngularJS modules, you can load them asynchronously and in any order as long
as you load this file first. Often the contents of this file are copy&pasted into the `index.html`
to avoid even the initial request to `angular-loader[.min].js`.
See [angular-seed](https://github.com/angular/angular-seed/blob/master/app/index-async.html) for
an example of usage.
* __Additional Angular modules:__ Optional modules with additional functionality. These files
* __Additional AngularJS modules:__ Optional modules with additional functionality. These files
should be loaded after the core `angular[.min].js` file:
* __`angular-animate.js`__ — Enable animation support. ({@link module:ngAnimate API docs})
* __`angular-aria.js`__ — Make your apps [accessible](http://www.w3.org/TR/wai-aria/) to users of
@@ -104,11 +104,11 @@ The set of files included in each version directory are:
messages in interpolated text. ({@link module:ngMessageFormat API docs})
* __`angular-messages.js`__ — Enhanced support for displaying validation messages.
({@link module:ngMessages API docs})
* __`angular-parse-ext.js`__ — Allow Unicode characters in identifiers inside Angular expressions.
* __`angular-parse-ext.js`__ — Allow Unicode characters in identifiers inside AngularJS expressions.
({@link module:ngParseExt API docs})
* __`angular-resource.js`__ — Easy interaction with RESTful services.
({@link module:ngResource API docs})
* __`angular-route.js`__ — Routing and deep-linking services and directives for Angular apps.
* __`angular-route.js`__ — Routing and deep-linking services and directives for AngularJS apps.
({@link module:ngRoute API docs})
* __`angular-sanitize.js`__ — Functionality to sanitize HTML. ({@link module:ngSanitize API docs})
* __`angular-touch.js`__ — Touch events and other helpers for touch-enabled devices.
@@ -120,4 +120,4 @@ The set of files included in each version directory are:
importantly, view the docs offline.
* __`i18n/`__ - This directory contains [locale specific](https://docs.angularjs.org/guide/i18n)
`ngLocale` Angular modules to override the defaults defined in the main `ng` module.
`ngLocale` AngularJS modules to override the defaults defined in the main `ng` module.
+7 -6
View File
@@ -8,7 +8,7 @@
### Why is this project called "AngularJS"? Why is the namespace called "ng"?
Because HTML has Angular brackets and "ng" sounds like "Angular".
Because HTML has AngularJS brackets and "ng" sounds like "AngularJS".
### Is AngularJS a library, framework, plugin or a browser extension?
@@ -94,7 +94,8 @@ When adding new code to AngularJS, we have a very stringent commit policy:
- Commit messages must be written in a specific manner that allows us to parse them and extract the changes
for release notes ([see the contributing guidelines](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md))
The AngularJS code base has a very large set of unit tests and end-to-end tests. This means that a breaking change will require one or more tests to be changed to allow the
The AngularJS code base has a very large set of unit tests and end-to-end tests. This means that
a breaking change will require one or more tests to be changed to allow the
tests to pass. So when a commit includes tests that are being removed or modified, this is a flag that the
code might include a breaking change. When reviewing the commit we can then decide whether there really is
a breaking change and if it is appropriate for the branch to which it is being merged. If so, then we
@@ -108,8 +109,8 @@ not used at Google or without sufficient test coverage, have a chance of making
### Is AngularJS a templating system?
At the highest level, Angular does look like just another templating system. But there is one
important reason why the Angular templating system is different, that makes it very good fit for
At the highest level, AngularJS does look like just another templating system. But there is one
important reason why the AngularJS templating system is different, that makes it very good fit for
application development: bidirectional data binding. The template is compiled in the browser and
the compilation step produces a live view. This means you, the developers, don't need to write
code to constantly sync the view with the model and the model with the view as in other
@@ -118,7 +119,7 @@ templating systems.
### Do I need to worry about security holes in AngularJS?
Like any other technology, AngularJS is not impervious to attack. Angular does, however, provide
Like any other technology, AngularJS is not impervious to attack. AngularJS does, however, provide
built-in protection from basic security holes, including cross-site scripting and HTML injection
attacks. AngularJS does round-trip escaping on all strings for you and even offers XSRF protection
for server-side communication.
@@ -127,7 +128,7 @@ AngularJS was designed to be compatible with other security measures like Conten
(CSP), HTTPS (SSL/TLS) and server-side authentication and authorization that greatly reduce the
possible attack vectors and we highly recommend their use.
Please read {@link security} for more detailed information about securing Angular apps.
Please read {@link security} for more detailed information about securing AngularJS apps.
### Can I download the source, build, and host the AngularJS environment locally?
+3 -3
View File
@@ -4,10 +4,10 @@
# Getting Started
We want you to have an easy time while starting to use Angular. We've put together the following steps on your path to
becoming an Angular expert.
We want you to have an easy time while starting to use AngularJS. We've put together the following steps on your path to
becoming an AngularJS expert.
1. Read the {@link guide/concepts conceptual overview}.<br/>Understand Angular's vocabulary and how all the Angular
1. Read the {@link guide/concepts conceptual overview}.<br/>Understand AngularJS's vocabulary and how all the AngularJS
components work together.
1. Do the {@link tutorial/ AngularJS Tutorial}.<br/>Walk end-to-end through building an application complete with tests
on top of a node.js web server. Covers every major AngularJS feature and shows you how to set up your development

Some files were not shown because too many files have changed in this diff Show More