Compare commits
308 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b168aef861 | |||
| 6c4d2707b7 | |||
| 9c95f6d5e0 | |||
| cab9ebfd5a | |||
| 8a739fb4fa | |||
| c4003fd034 | |||
| ab856d8ae3 | |||
| 83e6eef68e | |||
| 87270cb79f | |||
| e06ebfdbb5 | |||
| ddeb1df15a | |||
| 358a69fa8b | |||
| 417aefd45d | |||
| 6ad4c8d1b4 | |||
| 3ef612afa0 | |||
| cc8486f994 | |||
| b990fa91cd | |||
| 17f7d8c5c8 | |||
| 1e8dd0e65c | |||
| b1a18ef381 | |||
| 3470ab5696 | |||
| 5d39a118df | |||
| 421a5856f8 | |||
| 85f40a15fb | |||
| b919a2737e | |||
| a675ea0343 | |||
| 8fb8d52664 | |||
| d60d904747 | |||
| 62afb6204c | |||
| 1eaf4ab414 | |||
| 1de5d181da | |||
| 73088bb7ee | |||
| 898140edb7 | |||
| dab60352e5 | |||
| df4955fe78 | |||
| 14519488ce | |||
| 569e906a58 | |||
| 18b8a63a3c | |||
| 6e78fee732 | |||
| 6a99eaf1c8 | |||
| c94e44b9f8 | |||
| bbca6b0893 | |||
| 1555a4911a | |||
| dbba98b9ae | |||
| 3e2cb6c15c | |||
| 1391e99c7f | |||
| 7a5f06d55d | |||
| bf78beeb6d | |||
| 2e892e4072 | |||
| 8f88ea57dc | |||
| 24b0b516b6 | |||
| 1fcf5949d2 | |||
| 46ccaee9be | |||
| 86c9990813 | |||
| 4a34c8e1b8 | |||
| fec2ea8c1b | |||
| 7566c7d26f | |||
| 02a19c0f39 | |||
| 6e6e4eec9d | |||
| 46f14fa4b8 | |||
| bad2249bcd | |||
| c2148ec15c | |||
| 474e40498e | |||
| e9a6792d7f | |||
| adc1501caa | |||
| 7a53707c8f | |||
| 57fe5b320d | |||
| 671bebde0a | |||
| b51ded6736 | |||
| 3ec1819b91 | |||
| 009ebec64c | |||
| 9256dbc420 | |||
| 7504656a26 | |||
| e74cdf4b59 | |||
| 9d6c3f3ec2 | |||
| ac0e260765 | |||
| 28c0213ee5 | |||
| 8b4d85c015 | |||
| 2aeda67909 | |||
| ad68ee192e | |||
| 970ba117eb | |||
| 30e097b389 | |||
| e8e02b8bce | |||
| e36a3e89f5 | |||
| 1102c41196 | |||
| e970c8fce9 | |||
| 04271d6b2c | |||
| 2e1163ef5c | |||
| 75befe723a | |||
| 5e2bc5bbf3 | |||
| 079c485b92 | |||
| 19a0c9324c | |||
| 9ef02e72ab | |||
| 2101126ce7 | |||
| a222d0b452 | |||
| 1b8eb231c9 | |||
| 06baf1869b | |||
| 82597fc12b | |||
| ff52b188a7 | |||
| dc41f465ba | |||
| 6e3b5a57cd | |||
| f003d93a3d | |||
| aac5623247 | |||
| aa03812fd0 | |||
| bcb6a494de | |||
| a1e3f8728e | |||
| 9e8e3e187d | |||
| c6554433cf | |||
| 43d2a75f4e | |||
| 37d2b50812 | |||
| 8f31f1ff43 | |||
| cf84fcf544 | |||
| f63bc3cfde | |||
| a77943110e | |||
| ec97686f2f | |||
| 4ff7b7aa48 | |||
| 57b837bd5c | |||
| 6daca023e4 | |||
| 91b4eb0f69 | |||
| e50ed4da9e | |||
| fe5dd1da8f | |||
| df4c03fa33 | |||
| 8d4e626326 | |||
| 92aef5d456 | |||
| eed13cf732 | |||
| e90200b4de | |||
| 7f36ba77a0 | |||
| 457c58827b | |||
| aae768611f | |||
| ce5ffbf667 | |||
| ab114af850 | |||
| 2759788737 | |||
| c643323c17 | |||
| 9b97a033b0 | |||
| a3226d01fa | |||
| 510d0f946f | |||
| 0b962d4881 | |||
| 71b4daa4e1 | |||
| e0b02a5040 | |||
| a0dd9b0fdd | |||
| 498bef199a | |||
| 17d34b7a98 | |||
| 72359fd097 | |||
| 72882190f2 | |||
| fd2d8a5755 | |||
| fbe84f95a1 | |||
| 3671a43be4 | |||
| f6a1ad528d | |||
| d9128e7b23 | |||
| 0b54c1d4a9 | |||
| 608d623b55 | |||
| 9f30bb5475 | |||
| 182fb18f00 | |||
| 3a9fdceeee | |||
| ee4ac72170 | |||
| eb9fc571a0 | |||
| b4d1e5e492 | |||
| 60394a9d91 | |||
| f5ddb10b56 | |||
| 6a448d3459 | |||
| 6a8c0f5f4a | |||
| 584308fc06 | |||
| 48ad2c44bf | |||
| 100998330a | |||
| b9e85c62be | |||
| 77fad099d2 | |||
| e1f8a6e82b | |||
| 132d767647 | |||
| 9cde98cbc7 | |||
| 1ddbb3ec3e | |||
| 34f40266b2 | |||
| b8c06e3f1b | |||
| a6cf648b3c | |||
| aebde27f1b | |||
| c9be327d53 | |||
| 3dc7d22d90 | |||
| c10c6cac74 | |||
| cee2c4c569 | |||
| a5160c82dc | |||
| 8853312197 | |||
| 049b24de21 | |||
| a9f987a0c9 | |||
| ad4a20d3d2 | |||
| b3972d1b65 | |||
| c3e0d58b3c | |||
| f08156ea9b | |||
| 4bacf5a5da | |||
| df88873bb7 | |||
| c4b1c5e8f1 | |||
| 9822711ad2 | |||
| 30cd764b6d | |||
| 38b75cdb2d | |||
| 6cb8b39af8 | |||
| ebaa336614 | |||
| ef5f567f91 | |||
| 64e5afc478 | |||
| 1e582e4fa4 | |||
| 7421235f24 | |||
| 09ba69078d | |||
| 3536e83d8a | |||
| 3bb1dd5d7f | |||
| 95f964b827 | |||
| c8f78a8ca9 | |||
| f34d48087b | |||
| 2c9ecd01b1 | |||
| a584fb6e15 | |||
| 1f13313f40 | |||
| 5b60303781 | |||
| 10e2552a7d | |||
| ef48b0aa55 | |||
| f57872bca0 | |||
| 2deaf2877e | |||
| 7a146c9cd5 | |||
| 2796ec172b | |||
| 6997c1bf0c | |||
| 4a030f3834 | |||
| f78d8b8ff3 | |||
| f27d19ed60 | |||
| 4a5eaf7bec | |||
| 8513674911 | |||
| 97b74ad6fb | |||
| a47ea79023 | |||
| 5ca0de6487 | |||
| 50a449f053 | |||
| d7422da7d7 | |||
| c7cbc978c6 | |||
| 27146e8a7f | |||
| 5e418b1145 | |||
| f4bb973eb7 | |||
| 848857aa5b | |||
| ee8a05d3f1 | |||
| 275ebbf0ec | |||
| 0f23df4c06 | |||
| 11f700f7bd | |||
| 5785f2a991 | |||
| 2546c29f81 | |||
| 19ea708c9d | |||
| 5cf05d67f2 | |||
| 0377c6f0e8 | |||
| 9c13866824 | |||
| 419a4813e3 | |||
| 131af8272d | |||
| c219a46f59 | |||
| 25f008f541 | |||
| 4a593db79b | |||
| ad4fef0431 | |||
| 8a15fcc1f5 | |||
| f01212ab52 | |||
| 28693a1a67 | |||
| 29fd499552 | |||
| 2f97d9d647 | |||
| 4146b38459 | |||
| 05aab660ce | |||
| 5ecb64849e | |||
| 59dfe1b5a0 | |||
| 50ebfb735c | |||
| 0bdbfe5069 | |||
| 3fc4d6028c | |||
| 2eb12a052b | |||
| bd63b2235c | |||
| f418ffd083 | |||
| 6ab5f8ce4b | |||
| becfeb5aa3 | |||
| eb968c4a68 | |||
| 7f2af3f923 | |||
| cce98ff53a | |||
| b607618342 | |||
| fa50fbaf57 | |||
| f135e2dc05 | |||
| 780351db5e | |||
| a50bb0bfec | |||
| 4d86df6f48 | |||
| bb464d16b4 | |||
| 85b2eb1472 | |||
| 7608f92c6a | |||
| c0bf8db63c | |||
| c95a6737fb | |||
| cd43d24402 | |||
| 086c5d0354 | |||
| 2a2ac5f53a | |||
| 21deaf637a | |||
| 72e15a3a83 | |||
| 174cb4a8c8 | |||
| 33f769b0a1 | |||
| c8abf20558 | |||
| 6dbb183e75 | |||
| bc4844d3b2 | |||
| 708f8b47de | |||
| 5518126d42 | |||
| 5fe73fdc3a | |||
| 394c496bf2 | |||
| 8e1aeba715 | |||
| 0e6e7eb477 | |||
| 183f636816 | |||
| 5f8ed63f2a | |||
| e4f3c94e31 | |||
| 1e5cbcbd93 | |||
| dcf3ec160f | |||
| a7beb5b6d3 | |||
| 1d3b65adc2 | |||
| d528644fe3 | |||
| 6f1bcfc14e | |||
| 996914c6b0 | |||
| fff048d099 | |||
| dcb0da8225 | |||
| b664e20d12 | |||
| 3d68b95028 | |||
| 163aca336d |
+1
-1
@@ -1,4 +1,4 @@
|
||||
# https://editorconfig.org
|
||||
# http://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
|
||||
+2
-1
@@ -1,4 +1,6 @@
|
||||
bower_components/**
|
||||
build/**
|
||||
docs/bower_components/**
|
||||
docs/app/assets/js/angular-bootstrap/**
|
||||
docs/config/templates/**
|
||||
node_modules/**
|
||||
@@ -7,4 +9,3 @@ src/angular.bind.js
|
||||
src/ngParseExt/ucd.js
|
||||
i18n/closure/**
|
||||
tmp/**
|
||||
vendor/**
|
||||
|
||||
+2
-7
@@ -1,13 +1,8 @@
|
||||
{
|
||||
"extends": "./.eslintrc-base.json",
|
||||
|
||||
"env": {
|
||||
"browser": false,
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017
|
||||
},
|
||||
"plugins": [
|
||||
"promise"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- General PR submission guidelines https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#submit-pr -->
|
||||
<!-- General PR submission guidelines https://github.com/angular/angular.js/CONTRIBUTING.md#submit-pr -->
|
||||
**What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)**
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
|
||||
**Please check if the PR fulfills these requirements**
|
||||
- [ ] The commit message follows our [guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#commits)
|
||||
- [ ] Fix/Feature: [Docs](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#documentation) have been added/updated
|
||||
- [ ] The commit message follows our [guidelines](../DEVELOPERS.md#commits)
|
||||
- [ ] Fix/Feature: [Docs](../DEVELOPERS.md#documentation) have been added/updated
|
||||
- [ ] Fix/Feature: Tests have been added; existing tests pass
|
||||
|
||||
**Other information**:
|
||||
|
||||
+3
-2
@@ -1,5 +1,4 @@
|
||||
/build/
|
||||
/deploy/
|
||||
/benchpress-build/
|
||||
.DS_Store
|
||||
gen_docs.disable
|
||||
@@ -11,6 +10,7 @@ performance/temp*.html
|
||||
*.swp
|
||||
angular.js.tmproj
|
||||
node_modules/
|
||||
bower_components/
|
||||
angular.xcodeproj
|
||||
.idea
|
||||
*.iml
|
||||
@@ -19,6 +19,7 @@ angular.xcodeproj
|
||||
libpeerconnection.log
|
||||
npm-debug.log
|
||||
/tmp/
|
||||
/scripts/bower/bower-*
|
||||
.vscode
|
||||
*.log
|
||||
*.stackdump
|
||||
*.stackdump
|
||||
+9
-7
@@ -1,10 +1,12 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- '8'
|
||||
- '6'
|
||||
|
||||
cache:
|
||||
yarn: true
|
||||
directories:
|
||||
- bower_components
|
||||
|
||||
branches:
|
||||
except:
|
||||
@@ -26,12 +28,13 @@ env:
|
||||
- secure: oTBjhnOKhs0qDSKTf7fE4f6DYiNDPycvB7qfSF5QRIbJK/LK/J4UtFwetXuXj79HhUZG9qnoT+5e7lPaiaMlpsIKn9ann7ffqFWN1E8TMtpJF+AGigx3djYElwfgf5nEnFUFhwjFzvbfpZNnxVGgX5YbIZpe/WUbHkP4ffU0Wks=
|
||||
|
||||
before_install:
|
||||
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.3.2
|
||||
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 0.27.5
|
||||
- export PATH="$HOME/.yarn/bin:$PATH"
|
||||
|
||||
before_script:
|
||||
- du -sh ./node_modules || true
|
||||
- du -sh ./node_modules ./bower_components/ || true
|
||||
- "./scripts/travis/before_build.sh"
|
||||
|
||||
script:
|
||||
- "./scripts/travis/build.sh"
|
||||
|
||||
@@ -51,10 +54,10 @@ notifications:
|
||||
jobs:
|
||||
include:
|
||||
- stage: deploy
|
||||
# Don't deploy from PRs. Only deploy from our default branches, or if commit is tagged.
|
||||
# Don't deploy from PRs and only from our default branches.
|
||||
# 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)$ or tag IS present)
|
||||
if: type != pull_request and branch =~ ^(v1\.\d+\.x|master)$
|
||||
env:
|
||||
- JOB=deploy
|
||||
before_script: skip
|
||||
@@ -81,7 +84,6 @@ 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:
|
||||
@@ -94,7 +96,7 @@ jobs:
|
||||
secret_access_key:
|
||||
secure: tHIFdSq55qkyZf9zT/3+VkhUrTvOTMuswxXU3KyWaBrSieZqG0UnUDyNm+n3lSfX95zEl/+rJAWbfvhVSxZi13ndOtvRF+MdI1cvow2JynP0aDSiPffEvVrZOmihD6mt2SlMfhskr5FTduQ69kZG6DfLcve1PPDaIwnbOv3phb8=
|
||||
bucket: code-angularjs-org-338b8.appspot.com
|
||||
local-dir: deploy/code
|
||||
local-dir: uploadCode
|
||||
detect_encoding: true # detects gzip compression
|
||||
on:
|
||||
repo: angular/angular.js
|
||||
|
||||
+2
-2026
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
# 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.
|
||||
+10
-13
@@ -1,7 +1,6 @@
|
||||
# Developing AngularJS
|
||||
|
||||
* [Development Setup](#setup)
|
||||
* [Running Tests](#tests)
|
||||
* [Coding Rules](#rules)
|
||||
* [Commit Message Guidelines](#commits)
|
||||
* [Writing Documentation](#documentation)
|
||||
@@ -9,7 +8,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` and `grunt`.
|
||||
explains the basic mechanics of using `git`, `node`, `yarn`, `grunt`, and `bower`.
|
||||
|
||||
### Installing Dependencies
|
||||
|
||||
@@ -19,7 +18,7 @@ machine:
|
||||
* [Git](http://git-scm.com/): The [Github Guide to
|
||||
Installing Git][git-setup] is a good source of information.
|
||||
|
||||
* [Node.js v8.x (LTS)](http://nodejs.org): We use Node to generate the documentation, run a
|
||||
* [Node.js v6.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.
|
||||
|
||||
@@ -64,10 +63,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 JavaScript dependencies:
|
||||
# Install node.js dependencies:
|
||||
yarn install
|
||||
|
||||
# Build AngularJS:
|
||||
# Build AngularJS (which will install `bower` dependencies automatically):
|
||||
yarn grunt package
|
||||
```
|
||||
|
||||
@@ -108,8 +107,6 @@ 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
|
||||
@@ -119,7 +116,7 @@ tests once on Chrome run:
|
||||
yarn grunt test:unit
|
||||
```
|
||||
|
||||
To run the tests on other browsers use the command line flag:
|
||||
To run the tests on other browsers (Chrome, ChromeCanary, Firefox and Safari are pre-configured) use:
|
||||
|
||||
```shell
|
||||
yarn grunt test:unit --browsers=Chrome,Firefox
|
||||
@@ -128,15 +125,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. See the [karma config file](/karma-shared.conf.js) for all pre-configured browsers.
|
||||
via our pre-defined customLaunchers.
|
||||
|
||||
For example, to run the whole unit test suite on selected browsers:
|
||||
For example, to run the whole unit test suite:
|
||||
|
||||
```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_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_8,BS_iOS_9,BS_iOS_10
|
||||
# Saucelabs
|
||||
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
|
||||
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
|
||||
```
|
||||
|
||||
Running these commands requires you to set up [Karma Browserstack][karma-browserstack] or
|
||||
@@ -486,4 +483,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
|
||||
+23
-44
@@ -13,8 +13,6 @@ 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 + '). ' +
|
||||
@@ -164,12 +162,7 @@ module.exports = function(grunt) {
|
||||
|
||||
clean: {
|
||||
build: ['build'],
|
||||
tmp: ['tmp'],
|
||||
deploy: [
|
||||
'deploy/docs',
|
||||
'deploy/code',
|
||||
docsScriptFolder + '/functions/html'
|
||||
]
|
||||
tmp: ['tmp']
|
||||
},
|
||||
|
||||
eslint: {
|
||||
@@ -180,11 +173,11 @@ module.exports = function(grunt) {
|
||||
'docs/**/*.js',
|
||||
'lib/**/*.js',
|
||||
'scripts/**/*.js',
|
||||
'!scripts/*/*/node_modules/**',
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'i18n/**/*.js',
|
||||
'!docs/app/assets/js/angular-bootstrap/**',
|
||||
'!docs/bower_components/**',
|
||||
'!docs/config/templates/**',
|
||||
'!src/angular.bind.js',
|
||||
'!i18n/closure/**',
|
||||
@@ -194,6 +187,16 @@ module.exports = function(grunt) {
|
||||
},
|
||||
|
||||
build: {
|
||||
scenario: {
|
||||
dest: 'build/angular-scenario.js',
|
||||
src: [
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
util.wrap([files['angularSrc'], files['angularScenario']], 'ngScenario/angular')
|
||||
],
|
||||
styles: {
|
||||
css: ['css/angular.css', 'css/angular-scenario.css']
|
||||
}
|
||||
},
|
||||
angular: {
|
||||
dest: 'build/angular.js',
|
||||
src: util.wrap([files['angularSrc']], 'angular'),
|
||||
@@ -279,7 +282,9 @@ module.exports = function(grunt) {
|
||||
files: [
|
||||
'src/**/*.js',
|
||||
'test/**/*.js',
|
||||
'!test/ngScenario/DescribeSpec.js',
|
||||
'!src/ng/directive/attrs.js', // legitimate xit here
|
||||
'!src/ngScenario/**/*.js',
|
||||
'!test/helpers/privateMocks*.js'
|
||||
],
|
||||
options: {
|
||||
@@ -319,44 +324,19 @@ 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,js.map,min.js}', 'build/sitemap.xml'],
|
||||
dest: 'deploy/docs/',
|
||||
src: 'build/angular*.{js.map,min.js}',
|
||||
dest: 'uploadDocs/',
|
||||
expand: true,
|
||||
flatten: true
|
||||
},
|
||||
{
|
||||
cwd: 'build/docs',
|
||||
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',
|
||||
src: '**',
|
||||
dest: 'uploadDocs/',
|
||||
expand: true
|
||||
}
|
||||
]
|
||||
@@ -377,11 +357,10 @@ module.exports = function(grunt) {
|
||||
options: {
|
||||
mode: 'gzip'
|
||||
},
|
||||
// Already compressed files should not be compressed again
|
||||
src: ['**', '!**/*.{zip,png,jpeg,jpg}'],
|
||||
src: ['**'],
|
||||
cwd: 'build',
|
||||
expand: true,
|
||||
dest: 'deploy/code/' + deployVersion + '/'
|
||||
dest: 'uploadCode/' + deployVersion + '/'
|
||||
}
|
||||
},
|
||||
|
||||
@@ -460,12 +439,14 @@ 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',
|
||||
@@ -481,11 +462,9 @@ module.exports = function(grunt) {
|
||||
'merge-conflict',
|
||||
'eslint'
|
||||
]);
|
||||
grunt.registerTask('prepareDeploy', [
|
||||
grunt.registerTask('prepareFirebaseDeploy', [
|
||||
'package',
|
||||
'compress:deployFirebaseCode',
|
||||
'copy:deployFirebaseCode',
|
||||
'firebaseDocsJsonForTravis',
|
||||
'copy:deployFirebaseDocs'
|
||||
]);
|
||||
grunt.registerTask('default', ['package']);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2018 Google, Inc. http://angularjs.org
|
||||
Copyright (c) 2010-2017 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
@@ -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,
|
||||
AngularJS's $scope objects can be annotated as:
|
||||
Angular's $scope objects can be annotated as:
|
||||
```js
|
||||
/** @type {angular.Scope} */
|
||||
var scope = $scope;
|
||||
|
||||
@@ -12,14 +12,6 @@ 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!
|
||||
|
||||
--------------------
|
||||
|
||||
**On July 1, 2018 AngularJS entered a 3 year Long Term Support period:** [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
|
||||
@@ -28,6 +20,7 @@ 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
|
||||
--------------------
|
||||
@@ -79,7 +72,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 AngularJS will take care of the dependencies.
|
||||
moving parts, we simply define what we want and Angular 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
@@ -1,6 +1,6 @@
|
||||
# Triage new issues/PRs on github
|
||||
|
||||
This document shows the steps the AngularJS team is using to triage issues.
|
||||
This document shows the steps the Angular 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 AngularJS apps
|
||||
* high - impacts most or all Angular 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 AngularJS to accomplish something that AngularJS should be able to do
|
||||
* broken expected use - it's hard or impossible for a developer using Angular to accomplish something that Angular 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 to the npm registry.
|
||||
> 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.
|
||||
|
||||
|
||||
## Assigning Work
|
||||
|
||||
Vendored
+33
-10
@@ -28,7 +28,6 @@ var angularFiles = {
|
||||
'src/ng/httpBackend.js',
|
||||
'src/ng/interpolate.js',
|
||||
'src/ng/interval.js',
|
||||
'src/ng/intervalFactory.js',
|
||||
'src/ng/jsonpCallbacks.js',
|
||||
'src/ng/locale.js',
|
||||
'src/ng/location.js',
|
||||
@@ -41,7 +40,6 @@ var angularFiles = {
|
||||
'src/ng/sanitizeUri.js',
|
||||
'src/ng/sce.js',
|
||||
'src/ng/sniffer.js',
|
||||
'src/ng/taskTrackerFactory.js',
|
||||
'src/ng/templateRequest.js',
|
||||
'src/ng/testability.js',
|
||||
'src/ng/timeout.js',
|
||||
@@ -76,7 +74,6 @@ var angularFiles = {
|
||||
'src/ng/directive/ngNonBindable.js',
|
||||
'src/ng/directive/ngOptions.js',
|
||||
'src/ng/directive/ngPluralize.js',
|
||||
'src/ng/directive/ngRef.js',
|
||||
'src/ng/directive/ngRepeat.js',
|
||||
'src/ng/directive/ngShowHide.js',
|
||||
'src/ng/directive/ngStyle.js',
|
||||
@@ -106,13 +103,13 @@ var angularFiles = {
|
||||
'src/ngAnimate/animateJs.js',
|
||||
'src/ngAnimate/animateJsDriver.js',
|
||||
'src/ngAnimate/animateQueue.js',
|
||||
'src/ngAnimate/animateCache.js',
|
||||
'src/ngAnimate/animation.js',
|
||||
'src/ngAnimate/ngAnimateSwap.js',
|
||||
'src/ngAnimate/module.js'
|
||||
],
|
||||
'ngCookies': [
|
||||
'src/ngCookies/cookies.js',
|
||||
'src/ngCookies/cookieStore.js',
|
||||
'src/ngCookies/cookieWriter.js'
|
||||
],
|
||||
'ngMessageFormat': [
|
||||
@@ -134,7 +131,6 @@ var angularFiles = {
|
||||
],
|
||||
'ngRoute': [
|
||||
'src/shallowCopy.js',
|
||||
'src/routeToRegExp.js',
|
||||
'src/ngRoute/route.js',
|
||||
'src/ngRoute/routeParams.js',
|
||||
'src/ngRoute/directive/ngView.js'
|
||||
@@ -144,13 +140,13 @@ var angularFiles = {
|
||||
'src/ngSanitize/filter/linky.js'
|
||||
],
|
||||
'ngMock': [
|
||||
'src/routeToRegExp.js',
|
||||
'src/ngMock/angular-mocks.js',
|
||||
'src/ngMock/browserTrigger.js'
|
||||
],
|
||||
'ngTouch': [
|
||||
'src/ngTouch/touch.js',
|
||||
'src/ngTouch/swipe.js',
|
||||
'src/ngTouch/directive/ngClick.js',
|
||||
'src/ngTouch/directive/ngSwipe.js'
|
||||
],
|
||||
'ngAria': [
|
||||
@@ -158,8 +154,26 @@ var angularFiles = {
|
||||
]
|
||||
},
|
||||
|
||||
'angularScenario': [
|
||||
'src/ngScenario/Scenario.js',
|
||||
'src/ngScenario/Application.js',
|
||||
'src/ngScenario/Describe.js',
|
||||
'src/ngScenario/Future.js',
|
||||
'src/ngScenario/ObjectModel.js',
|
||||
'src/ngScenario/Runner.js',
|
||||
'src/ngScenario/SpecRunner.js',
|
||||
'src/ngScenario/dsl.js',
|
||||
'src/ngScenario/matchers.js',
|
||||
'src/ngScenario/output/Html.js',
|
||||
'src/ngScenario/output/Json.js',
|
||||
'src/ngScenario/output/Xml.js',
|
||||
'src/ngScenario/output/Object.js'
|
||||
],
|
||||
|
||||
'angularTest': [
|
||||
'test/helpers/*.js',
|
||||
'test/ngScenario/*.js',
|
||||
'test/ngScenario/output/*.js',
|
||||
'test/*.js',
|
||||
'test/auto/*.js',
|
||||
'test/ng/**/*.js',
|
||||
@@ -176,19 +190,26 @@ var angularFiles = {
|
||||
],
|
||||
|
||||
'karma': [
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'test/jquery_remove.js',
|
||||
'@angularSrc',
|
||||
'@angularSrcModules',
|
||||
'@angularScenario',
|
||||
'@angularTest'
|
||||
],
|
||||
|
||||
'karmaExclude': [
|
||||
'test/jquery_alias.js',
|
||||
'src/angular-bootstrap.js',
|
||||
'src/ngScenario/angular-bootstrap.js',
|
||||
'src/angular.bind.js'
|
||||
],
|
||||
|
||||
'karmaScenario': [
|
||||
'build/angular-scenario.js',
|
||||
'build/docs/docs-scenario.js'
|
||||
],
|
||||
|
||||
'karmaModules': [
|
||||
'build/angular.js',
|
||||
'@angularSrcModules',
|
||||
@@ -207,15 +228,17 @@ var angularFiles = {
|
||||
],
|
||||
|
||||
'karmaJquery': [
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'bower_components/jquery/dist/jquery.js',
|
||||
'test/jquery_alias.js',
|
||||
'@angularSrc',
|
||||
'@angularSrcModules',
|
||||
'@angularScenario',
|
||||
'@angularTest'
|
||||
],
|
||||
|
||||
'karmaJqueryExclude': [
|
||||
'src/angular-bootstrap.js',
|
||||
'src/ngScenario/angular-bootstrap.js',
|
||||
'test/jquery_remove.js',
|
||||
'src/angular.bind.js'
|
||||
]
|
||||
@@ -225,8 +248,8 @@ var angularFiles = {
|
||||
angularFiles['karmaJquery' + jQueryVersion] = []
|
||||
.concat(angularFiles.karmaJquery)
|
||||
.map(function(path) {
|
||||
if (path.startsWith('node_modules/jquery')) {
|
||||
return path.replace(/^node_modules\/jquery/, 'node_modules/jquery-' + jQueryVersion);
|
||||
if (path.startsWith('bower_components/jquery')) {
|
||||
return path.replace(/^bower_components\/jquery/, 'bower_components/jquery-' + jQueryVersion);
|
||||
}
|
||||
return path;
|
||||
});
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
// Override me with ?jquery=/node_modules/jquery/dist/jquery.js
|
||||
// Override me with ?jquery=/bower_components/jquery/dist/jquery.js
|
||||
|
||||
@@ -29,16 +29,19 @@ app.directive('bmPeWatch', function() {
|
||||
};
|
||||
});
|
||||
|
||||
//Executes the specified expression as a collection watcher
|
||||
app.directive('bmPeWatchCollection', function() {
|
||||
//Executes the specified expression as a watcher
|
||||
//Adds a simple wrapper method to allow use of $watch instead of $watchCollection
|
||||
app.directive('bmPeWatchLiteral', function($parse) {
|
||||
function retZero() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
compile: function($element, $attrs) {
|
||||
$element.text($attrs.bmPeWatchCollection);
|
||||
$element.text($attrs.bmPeWatchLiteral);
|
||||
return function($scope, $element, $attrs) {
|
||||
$scope.$watchCollection($attrs.bmPeWatchCollection, function(val) {
|
||||
$element.text(val);
|
||||
});
|
||||
$scope.$watch($parse($attrs.bmPeWatchLiteral, retZero));
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -69,7 +72,8 @@ app.controller('DataController', function($scope, $rootScope) {
|
||||
date2: new Date(Math.random() * Date.now()),
|
||||
func: function() { return star; },
|
||||
obj: data[i - 1],
|
||||
keys: data[i - 1] && (data[i - 1].keys || Object.keys(data[i - 1]))
|
||||
keys: data[i - 1] && (data[i - 1].keys || Object.keys(data[i - 1])),
|
||||
constructor: data[i - 1]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
<label for="complexPath">Complex Paths</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="constructorPath" id="constructorPath">
|
||||
<label for="constructorPath">Constructor Paths</label>
|
||||
($parse special cases "constructor" for security)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="fieldAccess" id="fieldAccess">
|
||||
<label for="fieldAccess">Field Accessors</label>
|
||||
@@ -60,16 +66,6 @@
|
||||
<input type="radio" ng-model="expressionType" value="arrayLiterals" id="arrayLiterals">
|
||||
<label for="arrayLiterals">Array Literals</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="watchCollection" id="watchCollection">
|
||||
<label for="watchCollection">$watchCollection</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<input type="radio" ng-model="expressionType" value="watchCollectionLiterals" id="watchCollectionLiterals">
|
||||
<label for="watchCollectionLiterals">$watchCollection Literals</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
@@ -92,6 +88,17 @@
|
||||
<span bm-pe-watch="row.keys"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="constructorPath" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="row.index"></span>
|
||||
<span bm-pe-watch="row.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.constructor.index"></span>
|
||||
<span bm-pe-watch="row.constructor.constructor.constructor.index"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="complexPath" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="row.index"></span>
|
||||
<span bm-pe-watch="row.num0"></span>
|
||||
@@ -208,44 +215,27 @@
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="objectLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="{foo: rowIdx}"></span>
|
||||
<span bm-pe-watch="{foo: row, bar: rowIdx}"></span>
|
||||
<span bm-pe-watch="{0: row, 1: rowIdx, 2: 3}"></span>
|
||||
<span bm-pe-watch="{str: 'foo', num: rowIdx, b: true}"></span>
|
||||
<span bm-pe-watch="{a: {b: {c: {d: {e: {f: rowIdx}}}}}}"></span>
|
||||
<span bm-pe-watch="{a: rowIdx, b: 1, c: 2, d: 3, e: 4, f: 5, g: rowIdx, h: 6, i: 7, j: 8, k: rowIdx}"></span>
|
||||
<span bm-pe-watch-literal="{foo: rowIdx}"></span>
|
||||
<span bm-pe-watch-literal="{foo: row, bar: rowIdx}"></span>
|
||||
<span bm-pe-watch-literal="{0: row, 1: rowIdx, 2: 3}"></span>
|
||||
<span bm-pe-watch-literal="{str: 'foo', num: rowIdx, b: true}"></span>
|
||||
<span bm-pe-watch-literal="{a: {b: {c: {d: {e: {f: rowIdx}}}}}}"></span>
|
||||
<span bm-pe-watch-literal="{a: rowIdx, b: 1, c: 2, d: 3, e: 4, f: 5, g: rowIdx, h: 6, i: 7, j: 8, k: rowIdx}"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="arrayLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch="[rowIdx]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0, 1]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0, 1, 2]"></span>
|
||||
<span bm-pe-watch="[rowIdx, 0, 1, 2, 3]"></span>
|
||||
<span bm-pe-watch="[[], [rowIdx], [], [], [3], [[[]]]]"></span>
|
||||
<span bm-pe-watch="[rowIdx, undefined, null, true, false]"></span>
|
||||
<span bm-pe-watch="[[][0], [0][0], [][rowIdx]]"></span>
|
||||
<span bm-pe-watch="[0, rowIdx]"></span>
|
||||
<span bm-pe-watch="[0, 1, rowIdx]"></span>
|
||||
<span bm-pe-watch="[0, 1, 2, rowIdx]"></span>
|
||||
<span bm-pe-watch="[0, 1, 2, 3, rowIdx]"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="watchCollection" ng-repeat="(rowIdx, row) in data">
|
||||
<span bm-pe-watch-collection="data"></span>
|
||||
<span bm-pe-watch-collection="row.keys"></span>
|
||||
<span bm-pe-watch-collection="thisProbablyDoesntHaveAValue"></span>
|
||||
</li>
|
||||
|
||||
<li ng-switch-when="watchCollectionLiterals" ng-repeat="(rowIdx, row) in ::data">
|
||||
<span bm-pe-watch-collection="[rowIdx, row]"></span>
|
||||
<span bm-pe-watch-collection="[rowIdx, row, num0, str0, date0, obj, g, h, i, j, k, l, m, n, o, p]"></span>
|
||||
<span bm-pe-watch-collection="{a: rowIdx, b: row, c: num0, d: str0, e: date0, f: obj, g: g, h: h, i: i, j: j, k: k, l: l, m: m, n: n, o: o, p: p}"></span>
|
||||
|
||||
<!-- primitive/valueOf-compatible -->
|
||||
<span bm-pe-watch-collection="[rowIdx, row]"></span>
|
||||
<span bm-pe-watch-collection="[rowIdx, num0, str0, date0, date1, h, i, j, k, l, m, n, o, p]"></span>
|
||||
<span bm-pe-watch-collection="{a: rowIdx, c: num0, d: str0, e: date0, g: date1, h: h, i: i, j: j, k: k, l: l, m: m, n: n, o: o, p: p}"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0, 1]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, 0, 1, 2, 3]"></span>
|
||||
<span bm-pe-watch-literal="[[], [rowIdx], [], [], [3], [[[]]]]"></span>
|
||||
<span bm-pe-watch-literal="[rowIdx, undefined, null, true, false]"></span>
|
||||
<span bm-pe-watch-literal="[[][0], [0][0], [][rowIdx]]"></span>
|
||||
<span bm-pe-watch-literal="[0, rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[0, 1, rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[0, 1, 2, rowIdx]"></span>
|
||||
<span bm-pe-watch-literal="[0, 1, 2, 3, rowIdx]"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('repeatAnimateBenchmark', ['ngAnimate'])
|
||||
.config(function($animateProvider) {
|
||||
$animateProvider.classNameFilter(/animate-/);
|
||||
})
|
||||
.run(function($rootScope) {
|
||||
$rootScope.fileType = 'classfilter';
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('repeatAnimateBenchmark', [])
|
||||
.run(function($rootScope) {
|
||||
$rootScope.fileType = 'noanimate';
|
||||
});
|
||||
@@ -1,7 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
angular.module('repeatAnimateBenchmark', ['ngAnimate'])
|
||||
.run(function($rootScope) {
|
||||
$rootScope.fileType = 'default';
|
||||
});
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/* eslint-env node */
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
scripts: [
|
||||
{
|
||||
id: 'angular',
|
||||
src: '/build/angular.js'
|
||||
},
|
||||
{
|
||||
id: 'angular-animate',
|
||||
src: '/build/angular-animate.js'
|
||||
},
|
||||
{
|
||||
id: 'app',
|
||||
src: 'app.js'
|
||||
},
|
||||
{
|
||||
src: 'common.js'
|
||||
}]
|
||||
});
|
||||
};
|
||||
@@ -1,120 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
var app = angular.module('repeatAnimateBenchmark');
|
||||
|
||||
app.config(function($compileProvider, $animateProvider) {
|
||||
if ($compileProvider.debugInfoEnabled) {
|
||||
$compileProvider.debugInfoEnabled(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
app.run(function($animate) {
|
||||
if ($animate.enabled) {
|
||||
$animate.enabled(true);
|
||||
}
|
||||
});
|
||||
|
||||
app.controller('DataController', function($scope, $rootScope, $animate) {
|
||||
var totalRows = 500;
|
||||
var totalColumns = 20;
|
||||
|
||||
var data = $scope.data = [];
|
||||
|
||||
function fillData() {
|
||||
if ($animate.enabled) {
|
||||
$animate.enabled($scope.benchmarkType !== 'globallyDisabled');
|
||||
}
|
||||
|
||||
for (var i = 0; i < totalRows; i++) {
|
||||
data[i] = [];
|
||||
for (var j = 0; j < totalColumns; j++) {
|
||||
data[i][j] = {
|
||||
i: i
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'enter',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
fillData();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
benchmarkSteps.push({
|
||||
name: 'leave',
|
||||
fn: function() {
|
||||
$scope.$apply(function() {
|
||||
data = $scope.data = [];
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.directive('disableAnimations', function($animate) {
|
||||
return {
|
||||
link: {
|
||||
pre: function(s, e) {
|
||||
$animate.enabled(e, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.directive('noop', function($animate) {
|
||||
return {
|
||||
link: {
|
||||
pre: angular.noop
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.directive('baseline', function($document) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $element) {
|
||||
var document = $document[0];
|
||||
|
||||
var i, j, row, cell, comment;
|
||||
var template = document.createElement('span');
|
||||
template.setAttribute('ng-repeat', 'foo in foos');
|
||||
template.classList.add('ng-scope');
|
||||
template.appendChild(document.createElement('span'));
|
||||
template.appendChild(document.createTextNode(':'));
|
||||
|
||||
function createList() {
|
||||
for (i = 0; i < $scope.data.length; i++) {
|
||||
row = document.createElement('div');
|
||||
$element[0].appendChild(row);
|
||||
for (j = 0; j < $scope.data[i].length; j++) {
|
||||
cell = template.cloneNode(true);
|
||||
row.appendChild(cell);
|
||||
cell.childNodes[0].textContent = i;
|
||||
cell.ng339 = 'xxx';
|
||||
comment = document.createComment('ngRepeat end: bar in foo');
|
||||
row.appendChild(comment);
|
||||
}
|
||||
|
||||
comment = document.createComment('ngRepeat end: foo in foos');
|
||||
$element[0].appendChild(comment);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.$watch('data.length', function(newVal) {
|
||||
if (newVal === 0) {
|
||||
while ($element[0].firstChild) {
|
||||
$element[0].removeChild($element[0].firstChild);
|
||||
}
|
||||
} else {
|
||||
createList();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
})();
|
||||
@@ -1,70 +0,0 @@
|
||||
<div ng-app="repeatAnimateBenchmark" ng-cloak>
|
||||
<div ng-controller="DataController">
|
||||
<div class="container-fluid">
|
||||
<p>
|
||||
Tests rendering of an ngRepeat with 500 elements.<br>
|
||||
Animations can be enabled / disabled in different ways.<br>
|
||||
Two tests require reloading the app with different module / app configurations.
|
||||
</p>
|
||||
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="none">none: </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" value="baseline">baseline (vanilla Javascript): </label></div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default'" value="enabled">enabled : </label> (requires <a href="./">app.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default' && fileType !== 'classfilter'" value="globallyDisabled">globally disabled:</label> (requires <a href="./">app.js</a> or <a href="?app=app-classfilter.js">app-classfilter.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'default'" value="disabledParentElement">disabled by $animate.enabled() on parent element: </label> (requires <a href="./">app.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'noanimate'" value="noanimate">Without ngAnimate:</label> (requires <a href="?app=app-noanimate.js">app-noanimate.js</a>)</div>
|
||||
<div><label><input type="radio" ng-model="benchmarkType" ng-disabled="fileType !== 'classfilter'" value="disabledClassFilter">disabled by classNameFilter on element:</label> (requires <a href="?app=app-classfilter.js">app-classfilter.js</a>)</div>
|
||||
|
||||
<ng-switch on="benchmarkType">
|
||||
<baseline ng-switch-when="baseline">
|
||||
</baseline>
|
||||
<div ng-switch-when="noanimate">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="enabled">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="globallyDisabled">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="disabledClassFilter">
|
||||
<div noop>
|
||||
<div ng-repeat="row in data">
|
||||
<span class="disable-animations" ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ng-switch-when="disabledParentElement">
|
||||
<div disable-animations>
|
||||
<div ng-repeat="row in data">
|
||||
<span ng-repeat="column in row">
|
||||
<span>{{column.i}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-switch>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,7 @@ body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#json,
|
||||
#xml {
|
||||
#json, #xml {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
+2
-6
@@ -1,11 +1,7 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
[ng\:cloak],
|
||||
[ng-cloak],
|
||||
[data-ng-cloak],
|
||||
[x-ng-cloak],
|
||||
.ng-cloak,
|
||||
.x-ng-cloak,
|
||||
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],
|
||||
.ng-cloak, .x-ng-cloak,
|
||||
.ng-hide:not(.ng-hide-animate) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -713,14 +713,14 @@ ul.events > li {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) {
|
||||
@media only screen and (min-width: 769px) {
|
||||
[ng-include="partialPath"].ng-hide {
|
||||
display: block !important;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 768px) and (max-width: 991px) {
|
||||
@media only screen and (min-width: 769px) and (max-width: 991px) {
|
||||
.main-body-grid {
|
||||
margin-top: 160px;
|
||||
}
|
||||
@@ -729,7 +729,7 @@ ul.events > li {
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767px) {
|
||||
@media only screen and (max-width : 768px) {
|
||||
.picker, .picker select {
|
||||
width: auto;
|
||||
display: block;
|
||||
@@ -934,14 +934,6 @@ 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;
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
User-agent: *
|
||||
|
||||
# The map files are not required by the app
|
||||
Disallow: /*.map$
|
||||
@@ -9,7 +9,6 @@
|
||||
},
|
||||
|
||||
"globals": {
|
||||
"angular": false,
|
||||
/* testabilityPatch / matchers */
|
||||
"inject": false,
|
||||
"module": false,
|
||||
|
||||
@@ -21,9 +21,6 @@ describe('docs.angularjs.org', function() {
|
||||
console.log('browser console errors: ' + require('util').inspect(filteredLog));
|
||||
}
|
||||
});
|
||||
|
||||
browser.ignoreSynchronization = false;
|
||||
browser.clearMockModules();
|
||||
});
|
||||
|
||||
|
||||
@@ -105,66 +102,6 @@ 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);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
describe('table of contents', function() {
|
||||
|
||||
it('on provider pages', function() {
|
||||
browser.get('build/docs/index.html#!/api/ng/provider/$controllerProvider');
|
||||
browser.get('build/docs/index.html#!/api/ng/provider/$interpolateProvider');
|
||||
|
||||
var toc = element.all(by.css('toc-container > div > toc-tree'));
|
||||
toc.getText().then(function(text) {
|
||||
@@ -19,7 +19,7 @@ describe('table of contents', function() {
|
||||
var tocFirstLevel = element.all(by.css('toc-container > div > toc-tree > ul > li'));
|
||||
|
||||
tocFirstLevel.then(function(match) {
|
||||
expect(match.length).toBe(2);
|
||||
expect(match.length).toBe(3);
|
||||
|
||||
expect(match[1].all(by.css('li')).count()).toBe(2);
|
||||
});
|
||||
|
||||
@@ -91,16 +91,13 @@ directivesModule
|
||||
.component('tocTree', {
|
||||
template: '<ul>' +
|
||||
'<li ng-repeat="item in $ctrl.items">' +
|
||||
'<a ng-href="{{ $ctrl.path }}#{{item.fragment}}">{{item.title}}</a>' +
|
||||
'<a ng-href="#{{item.fragment}}">{{item.title}}</a>' +
|
||||
'<toc-tree ng-if="::item.children.length > 0" items="item.children"></toc-tree>' +
|
||||
'</li>' +
|
||||
'</ul>',
|
||||
bindings: {
|
||||
items: '<'
|
||||
},
|
||||
controller: ['$location', /** @this */ function($location) {
|
||||
this.path = $location.path().replace(/^\/?(.+?)(\/index)?\/?$/, '$1');
|
||||
}]
|
||||
}
|
||||
})
|
||||
.directive('tocContainer', function() {
|
||||
return {
|
||||
|
||||
+5
-11
@@ -8,8 +8,6 @@ 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,
|
||||
@@ -18,6 +16,8 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
$scope.$on('$includeContentLoaded', function() {
|
||||
var pagePath = $scope.currentPage ? $scope.currentPage.path : $location.path();
|
||||
$window._gaq.push(['_trackPageview', pagePath]);
|
||||
@@ -26,7 +26,6 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
|
||||
$scope.$on('$includeContentError', function() {
|
||||
$scope.loading = false;
|
||||
$scope.loadingError = true;
|
||||
});
|
||||
|
||||
$scope.$watch(function docsPathWatch() {return $location.path(); }, function docsPathWatchAction(path) {
|
||||
@@ -36,7 +35,6 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
var currentPage = $scope.currentPage = NG_PAGES[path];
|
||||
|
||||
$scope.loading = true;
|
||||
$scope.loadingError = false;
|
||||
|
||||
if (currentPage) {
|
||||
$scope.partialPath = 'partials/' + path + '.html';
|
||||
@@ -52,22 +50,18 @@ angular.module('DocsController', ['currentVersionData'])
|
||||
} else {
|
||||
$scope.currentArea = NG_NAVIGATION['api'];
|
||||
$scope.breadcrumb = [];
|
||||
$scope.partialPath = errorPartialPath;
|
||||
$scope.partialPath = 'Error404.html';
|
||||
}
|
||||
});
|
||||
|
||||
$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 = false;
|
||||
$scope.loadingError = false;
|
||||
$scope.loading = 0;
|
||||
|
||||
|
||||
var INDEX_PATH = /^(\/|\/index[^.]*.html)$/;
|
||||
if (!$location.path() || INDEX_PATH.test($location.path())) {
|
||||
|
||||
@@ -22,7 +22,6 @@ 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'))
|
||||
@@ -32,7 +31,6 @@ 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) {
|
||||
@@ -148,7 +146,6 @@ module.exports = new Package('angularjs', [
|
||||
|
||||
.config(function(checkAnchorLinksProcessor) {
|
||||
checkAnchorLinksProcessor.base = '/';
|
||||
checkAnchorLinksProcessor.errorOnUnmatchedLinks = true;
|
||||
// We are only interested in docs that have an area (i.e. they are pages)
|
||||
checkAnchorLinksProcessor.checkDoc = function(doc) { return doc.area; };
|
||||
})
|
||||
@@ -159,14 +156,12 @@ module.exports = new Package('angularjs', [
|
||||
generateProtractorTestsProcessor,
|
||||
generateExamplesProcessor,
|
||||
debugDeployment, defaultDeployment,
|
||||
jqueryDeployment, testDeployment,
|
||||
productionDeployment) {
|
||||
jqueryDeployment, productionDeployment) {
|
||||
|
||||
generateIndexPagesProcessor.deployments = [
|
||||
debugDeployment,
|
||||
defaultDeployment,
|
||||
jqueryDeployment,
|
||||
testDeployment,
|
||||
productionDeployment
|
||||
];
|
||||
|
||||
|
||||
@@ -5,36 +5,18 @@
|
||||
* @description
|
||||
* Process "error" docType docs and generate errorNamespace docs
|
||||
*/
|
||||
module.exports = function errorDocsProcessor(log, errorNamespaceMap, getMinerrInfo) {
|
||||
module.exports = function errorDocsProcessor(errorNamespaceMap, getMinerrInfo) {
|
||||
return {
|
||||
$runAfter: ['tags-extracted'],
|
||||
$runBefore: ['extra-docs-added'],
|
||||
$process: function(docs) {
|
||||
|
||||
// Get the extracted min errors to compare with the error docs, and report any mismatch
|
||||
var collectedErrors = require('../../../build/errors.json').errors;
|
||||
var flatErrors = [];
|
||||
|
||||
for (var namespace in collectedErrors) {
|
||||
for (var error in collectedErrors[namespace]) {
|
||||
flatErrors.push(namespace + ':' + error);
|
||||
}
|
||||
}
|
||||
|
||||
// Create error namespace docs and attach error docs to each
|
||||
docs.forEach(function(doc) {
|
||||
var parts, namespaceDoc;
|
||||
|
||||
if (doc.docType === 'error') {
|
||||
|
||||
var matchingMinErr = flatErrors.indexOf(doc.name);
|
||||
|
||||
if (matchingMinErr === -1) {
|
||||
log.warn('Error doc: ' + doc.name + ' has no matching min error');
|
||||
} else {
|
||||
flatErrors.splice(matchingMinErr, 1);
|
||||
}
|
||||
|
||||
// Parse out the error info from the id
|
||||
parts = doc.name.split(':');
|
||||
doc.namespace = parts[0];
|
||||
@@ -59,10 +41,6 @@ module.exports = function errorDocsProcessor(log, errorNamespaceMap, getMinerrIn
|
||||
}
|
||||
});
|
||||
|
||||
flatErrors.forEach(function(value) {
|
||||
log.warn('No error doc exists for min error: ' + value);
|
||||
});
|
||||
|
||||
errorNamespaceMap.forEach(function(errorNamespace) {
|
||||
docs.push(errorNamespace);
|
||||
});
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
'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;
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -55,6 +55,9 @@ 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;
|
||||
@@ -82,9 +85,6 @@ 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,15 +130,14 @@ 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 = version.version;
|
||||
var semverObj = semver.parse(version);
|
||||
return semverObj === null ? false : !semverObj.prerelease.length;
|
||||
}
|
||||
|
||||
function createSnapshotStableLabel(version) {
|
||||
var label = version.label.replace(/.$/, 'x') + '-snapshot';
|
||||
var label = 'v' + version.replace(/.$/, 'x') + '-snapshot';
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
'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'
|
||||
]
|
||||
};
|
||||
};
|
||||
@@ -4,13 +4,14 @@ var path = require('canonical-path');
|
||||
/**
|
||||
* dgService getVersion
|
||||
* @description
|
||||
* Find the current version of the node module
|
||||
* Find the current version of the bower component (or node module)
|
||||
*/
|
||||
module.exports = function getVersion(readFilesProcessor) {
|
||||
var sourceFolder = path.resolve(readFilesProcessor.basePath, 'node_modules');
|
||||
var packageFile = 'package.json';
|
||||
var basePath = readFilesProcessor.basePath;
|
||||
|
||||
return function(component) {
|
||||
return require(path.join(sourceFolder, component, packageFile)).version;
|
||||
return function(component, sourceFolder, packageFile) {
|
||||
sourceFolder = path.resolve(basePath, sourceFolder || 'node_modules');
|
||||
packageFile = packageFile || 'package.json';
|
||||
return require(path.join(sourceFolder,component,packageFile)).version;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,18 +11,6 @@
|
||||
<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
|
||||
@@ -139,7 +127,7 @@
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="search-results-container" ng-show="hasResults" ng-cloak>
|
||||
<div class="search-results-container" ng-show="hasResults">
|
||||
<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">
|
||||
@@ -169,7 +157,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<nav id="navbar-sub" class="sup-header navbar navbar-fixed-top" scroll-y-offset-element ng-cloak>
|
||||
<nav id="navbar-sub" class="sup-header navbar navbar-fixed-top" scroll-y-offset-element>
|
||||
<div class="container main-grid main-header-grid">
|
||||
<div class="grid-left">
|
||||
<version-picker></version-picker>
|
||||
@@ -186,7 +174,7 @@
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<section role="main" class="container main-body" ng-cloak>
|
||||
<section role="main" class="container main-body">
|
||||
<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>
|
||||
@@ -210,8 +198,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid-right">
|
||||
<div ng-show="loading">Loading …</div>
|
||||
<div ng-show="loadingError">There was an error loading this resource. Please try again later.</div>
|
||||
<div id="loading" ng-show="loading">Loading...</div>
|
||||
<div ng-hide="loading" ng-include="partialPath" toc-collector autoscroll></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -222,10 +209,10 @@
|
||||
<p class="pull-right"><a back-to-top>Back to top</a></p>
|
||||
|
||||
<p>
|
||||
Super-powered by Google ©2010-2018
|
||||
Super-powered by Google ©2010-2017
|
||||
(<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 AngularJS">
|
||||
ng-bind-template="v{{version}}" title="Changelog of this version of Angular JS">
|
||||
</a>)
|
||||
</p>
|
||||
<p>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<?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>
|
||||
@@ -3,15 +3,7 @@
|
||||
@description
|
||||
|
||||
# AngularJS API Docs
|
||||
|
||||
<div class="alert alert-warning">
|
||||
**On July 1, 2018 AngularJS entered a 3 year Long Term Support period:** [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>.
|
||||
|
||||
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.
|
||||
@@ -19,14 +11,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">
|
||||
**AngularJS Prefixes `$` and `$$`**:
|
||||
**Angular Prefixes `$` and `$$`**:
|
||||
|
||||
To prevent accidental name collisions with your code,
|
||||
AngularJS prefixes names of public objects with `$` and names of private objects with `$$`.
|
||||
Angular prefixes names of public objects with `$` and names of private objects with `$$`.
|
||||
Please do not use the `$` or `$$` prefix in your code.
|
||||
</div>
|
||||
|
||||
## AngularJS Modules
|
||||
## Angular Modules
|
||||
|
||||
|
||||
## {@link ng ng (core module)}
|
||||
@@ -91,7 +83,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:
|
||||
@@ -138,7 +130,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 AngularJS directives will provide
|
||||
Use ngAnimate to enable animation features within your application. Various core ng directives will provide
|
||||
animation hooks into your application when ngAnimate is included. Animations are defined by using CSS transitions/animations
|
||||
or JavaScript callbacks.
|
||||
|
||||
@@ -222,7 +214,11 @@ Use the ngCookies module to handle cookie management within your application.
|
||||
{@link ngCookies#service Services / Factories}
|
||||
</td>
|
||||
<td>
|
||||
The {@link ngCookies.$cookies $cookies} service is a convenient wrapper to store simple data within browser cookies.
|
||||
The following services are used for cookie management:
|
||||
<ul>
|
||||
<li>The {@link ngCookies.$cookies $cookie} service is a convenient wrapper to store simple data within browser cookies.</li>
|
||||
<li>{@link ngCookies.$cookieStore $cookieStore} is used to store more complex data using serialization.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:ctxoverride
|
||||
@fullName DOM Property Security Context Override
|
||||
@description
|
||||
|
||||
This error occurs when the security context for a property is defined via {@link ng.$compileProvider#addPropertySecurityContext addPropertySecurityContext()} multiple times under different security contexts.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
$compileProvider.addPropertySecurityContext("my-element", "src", $sce.MEDIA_URL);
|
||||
$compileProvider.addPropertySecurityContext("my-element", "src", $sce.RESOURCE_URL); //throws
|
||||
```
|
||||
@@ -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.
|
||||
AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
Angular 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:
|
||||
|
||||
@@ -10,15 +10,13 @@ myModule.directive('directiveName', function factory() {
|
||||
return {
|
||||
...
|
||||
scope: {
|
||||
'localName': '@', // OK
|
||||
'localName2': '&attr', // OK
|
||||
'localName3': '<?attr', // OK
|
||||
'localName4': ' = attr', // OK
|
||||
'localName5': ' =*attr', // OK
|
||||
'localName6': 'attr', // ERROR: missing mode @&=<
|
||||
'localName7': 'attr=', // ERROR: must be prefixed with @&=<
|
||||
'localName8': '=attr?', // ERROR: ? must come directly after the mode
|
||||
'localName9': '<*' // ERROR: * is only valid with =
|
||||
'attrName': '@', // OK
|
||||
'attrName2': '=localName', // OK
|
||||
'attrName3': '<?localName', // OK
|
||||
'attrName4': ' = name', // OK
|
||||
'attrName5': 'name', // ERROR: missing mode @&=
|
||||
'attrName6': 'name=', // ERROR: must be prefixed with @&=
|
||||
'attrName7': '=name?', // ERROR: ? must come directly after the mode
|
||||
}
|
||||
...
|
||||
}
|
||||
|
||||
@@ -3,34 +3,6 @@
|
||||
@fullName Missing required attribute
|
||||
@description
|
||||
|
||||
This error may occur only when {@link $compileProvider#strictComponentBindingsEnabled `$compileProvider.strictComponentBindingsEnabled`} is set to `true`.
|
||||
|
||||
If that is the case, then all {@link $compileProvider#component component} controller bindings and
|
||||
{@link $compileProvider#directive directive} scope / controller bindings that are non-optional,
|
||||
must be provided when the directive is instantiated.
|
||||
|
||||
To make a binding optional, add '?' to the definition.
|
||||
|
||||
## Example:
|
||||
|
||||
```js
|
||||
|
||||
app.component('myTest', {
|
||||
bindings: {
|
||||
first: '=?', // optional
|
||||
second: '='
|
||||
},
|
||||
controller: function() {
|
||||
...
|
||||
},
|
||||
template: '...'
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
This component will throw `missingattr` for the `second` binding when used as follows:
|
||||
|
||||
```html
|
||||
<my-test></my-test>
|
||||
```
|
||||
|
||||
This error may occur only when `$compileProvider.strictComponentBindingsEnabled` is set to `true`.
|
||||
Then all attributes mentioned in `bindings` without `?` must be set. If one or more aren't set,
|
||||
the first one will throw an error.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
@ngdoc error
|
||||
@name $compile:nodomevents
|
||||
@fullName Event Attribute/Property Binding
|
||||
@fullName Interpolated Event Attributes
|
||||
@description
|
||||
|
||||
This error occurs when one tries to create a binding for event handler attributes or properties like `onclick`, `onload`, `onsubmit`, etc.
|
||||
This error occurs when one tries to create a binding for event handler attributes like `onclick`, `onload`, `onsubmit`, etc.
|
||||
|
||||
There is no practical value in binding to these attributes/properties and doing so only exposes your application to security vulnerabilities like XSS.
|
||||
For these reasons binding to event handler attributes and properties (`formaction` and all starting with `on`) is not supported.
|
||||
There is no practical value in binding to these attributes and doing so only exposes your application to security vulnerabilities like XSS.
|
||||
For these reasons binding to event handler attributes (all attributes that start with `on` and `formaction` attribute) is not supported.
|
||||
|
||||
|
||||
An example code that would allow XSS vulnerability by evaluating user input in the window context could look like this:
|
||||
@@ -17,4 +17,4 @@ An example code that would allow XSS vulnerability by evaluating user input in t
|
||||
|
||||
Since the `onclick` evaluates the value as JavaScript code in the window context, setting the `username` model to a value like `javascript:alert('PWND')` would result in script injection when the `div` is clicked.
|
||||
|
||||
Please use the `ng-*` or `ng-on-*` versions instead (such as `ng-click` or `ng-on-click` rather than `onclick`).
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $compile:srcset
|
||||
@fullName Invalid value passed to `attr.$set('srcset', value)`
|
||||
@description
|
||||
|
||||
This error occurs if you try to programmatically set the `srcset` attribute with a non-string value.
|
||||
|
||||
This can be the case if you tried to avoid the automatic sanitization of the `srcset` value by
|
||||
passing a "trusted" value provided by calls to `$sce.trustAsMediaUrl(value)`.
|
||||
|
||||
If you want to programmatically set explicitly trusted unsafe URLs, you should use `$sce.trustAsHtml`
|
||||
on the whole `img` tag and inject it into the DOM using the `ng-bind-html` directive.
|
||||
@@ -0,0 +1,11 @@
|
||||
@ngdoc error
|
||||
@name $compile:tpload
|
||||
@fullName Error Loading Template
|
||||
@description
|
||||
|
||||
This error occurs when {@link ng.$compile `$compile`} attempts to fetch a template from some URL, and the request fails.
|
||||
|
||||
To resolve this error, ensure that the URL of the template is spelled correctly and resolves to correct absolute URL.
|
||||
The [Chrome Developer Tools](https://developers.google.com/chrome-developer-tools/docs/network#network_panel_overview) might also be helpful in determining why the request failed.
|
||||
|
||||
If you are using {@link ng.$templateCache} to pre-load templates, ensure that the cache was populated with the template.
|
||||
@@ -9,9 +9,9 @@ value is `JSON_CALLBACK`.
|
||||
|
||||
`$http` JSONP requests need to attach a callback query parameter to the URL. The name of this
|
||||
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 configuration of the request.
|
||||
property. You must not provide your own parameter with this name in the configuratio of the request.
|
||||
|
||||
In previous versions of AngularJS, you specified where to add the callback parameter value via the
|
||||
In previous versions of Angular, 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`;
|
||||
|
||||
@@ -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 AngularJS's `ng` module
|
||||
### Monkey-patching Angular'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 AngularJS expression is missing the corresponding closing operator.
|
||||
The Angular 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 AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular 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 AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular 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 AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
@description
|
||||
|
||||
You must specify the MessageFormat function that you're using right after the
|
||||
comma following the AngularJS expression. Currently, the supported functions are
|
||||
comma following the Angular 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 AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular 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 AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular 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 AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular 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 AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular 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 AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular 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 AngularJS i18n MessageFormat}
|
||||
{@link guide/i18n#MessageFormat Angular i18n MessageFormat}
|
||||
|
||||
@@ -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 AngularJS i18n MessageFormat}.
|
||||
guide/i18n#MessageFormat Angular i18n MessageFormat}.
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
@fullName Unterminated string literal
|
||||
@description
|
||||
|
||||
The string literal was not terminated in your AngularJS expression.
|
||||
The string literal was not terminated in your Angular expression.
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $interval:badprom
|
||||
@fullName Non-$interval promise
|
||||
@description
|
||||
|
||||
This error occurs when calling {@link ng.$interval#cancel $interval.cancel()} with a promise that
|
||||
was not generated by the {@link ng.$interval $interval} service. This can, for example, happen when
|
||||
calling {@link ng.$q#the-promise-api then()/catch()} on the returned promise, which creates a new
|
||||
promise, and pass that new promise to {@link ng.$interval#cancel $interval.cancel()}.
|
||||
|
||||
Example of incorrect usage that leads to this error:
|
||||
|
||||
```js
|
||||
var promise = $interval(doSomething, 1000, 5).then(doSomethingElse);
|
||||
$interval.cancel(promise);
|
||||
```
|
||||
|
||||
To fix the example above, keep a reference to the promise returned by
|
||||
{@link ng.$interval $interval()} and pass that to {@link ng.$interval#cancel $interval.cancel()}:
|
||||
|
||||
```js
|
||||
var promise = $interval(doSomething, 1000, 5);
|
||||
var newPromise = promise.then(doSomethingElse);
|
||||
$interval.cancel(promise);
|
||||
```
|
||||
@@ -40,7 +40,7 @@ URL of the subcontext:
|
||||
</head>
|
||||
```
|
||||
|
||||
Before AngularJS 1.3 we didn't have this hard requirement and it was easy to write apps that worked
|
||||
Before Angular 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:
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
@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.
|
||||
@@ -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 AngularJS expressions}, identify the error and fix the expression's syntax.
|
||||
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and fix the expression's syntax.
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
@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';
|
||||
```
|
||||
@@ -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 AngularJS expressions}, identify the error and fix the expression's syntax.
|
||||
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and fix the expression's syntax.
|
||||
|
||||
@@ -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 AngularJS expressions}, identify the error and
|
||||
To resolve, learn more about {@link guide/expression Angular expressions}, identify the error and
|
||||
fix the expression's syntax.
|
||||
|
||||
@@ -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.
|
||||
AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.
|
||||
Angular 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, AngularJS determines that the model is different on each `$digest`
|
||||
Since `getUsers()` returns a new array, Angular 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:
|
||||
|
||||
|
||||
@@ -10,17 +10,17 @@ the error.
|
||||
|
||||
## Background
|
||||
|
||||
AngularJS uses a dirty-checking digest mechanism to monitor and update values of the scope during
|
||||
Angular 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 AngularJS application code
|
||||
application, such as mouse events, timeouts or server responses, wrap the Angular application code
|
||||
in a block of code that will run `$digest` when the code completes.
|
||||
|
||||
You wrap AngularJS code in a block that will be followed by a `$digest` by calling `$apply` on a scope
|
||||
You wrap Angular 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
|
||||
|
||||
AngularJS keeps track of what phase of processing we are in, the relevant ones being `$apply` and
|
||||
Angular 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 AngularJS will throw this error when
|
||||
typically a sign of programming error that needs to be fixed. So Angular 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 AngularJS scope or services, in a call to
|
||||
case you should wrap any code that will be interacting with Angular scope or services, in a call to
|
||||
`$apply`.
|
||||
|
||||
As an example, all Controller code should expect to be run within AngularJS, so it should have no need
|
||||
As an example, all Controller code should expect to be run within Angular, 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 AngularJS, and so any AngularJS application code that it calls should first be wrapped in a call
|
||||
within Angular, and so any Angular 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 AngularJS. Therefore, we
|
||||
correctly wrap our application code that interacts with AngularJS in a call to `$apply`.
|
||||
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`.
|
||||
|
||||
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 AngularJS), which is normally called by an external trigger.
|
||||
programmatically (from within Angular), 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 AngularJS not to wrap this `fn` in an
|
||||
by using `$timeout(fn, 0, false)`, where the `false` value tells Angular 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 AngularJS directive then it is likely that it matches the second
|
||||
* If the second call was made inside an Angular 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 AngularJS code is minified) that there were two calls to `$apply`, first
|
||||
We can see (even though the Angular 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 AngularJS directive.
|
||||
this call is made by an Angular 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 AngularJS processing model please check out the
|
||||
To learn more about Angular processing model please check out the
|
||||
{@link guide/concepts concepts doc} as well as the {@link ng.$rootScope.Scope api} doc.
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
@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.
|
||||
@@ -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 AngularJS'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 Angular's `$sanitize` is being used on an unsupported platform.
|
||||
|
||||
@@ -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 AngularJS template from an untrusted source.
|
||||
Typically, this would occur if you're attempting to load an Angular template from an untrusted source.
|
||||
It's also possible that a custom directive threw this error for a similar reason.
|
||||
|
||||
AngularJS only loads templates from trusted URLs (by calling {@link ng.$sce#getTrustedResourceUrl $sce.getTrustedResourceUrl} on the template URL).
|
||||
Angular 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.
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
The value provided for use in a specific context was not found to be safe/trusted for use.
|
||||
|
||||
AngularJS's {@link ng.$sce Strict Contextual Escaping (SCE)} mode
|
||||
Angular'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
|
||||
AngularJS template from a URL requires that the URL is one considered safe for loading resources.)
|
||||
Angular 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)}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $templateRequest:tpload
|
||||
@fullName Error Loading Template
|
||||
@description
|
||||
|
||||
This error occurs when {@link $templateRequest} attempts to fetch a template from some URL, and
|
||||
the request fails.
|
||||
|
||||
The template URL might be defined in a directive/component definition, an instance of `ngInclude`,
|
||||
an instance of `ngMessagesInclude` or a templated route in a `$route` route definition.
|
||||
|
||||
To resolve this error, ensure that the URL of the template is spelled correctly and resolves to
|
||||
correct absolute URL.
|
||||
The [Chrome Developer Tools](https://developers.google.com/chrome-developer-tools/docs/network#network_panel_overview)
|
||||
might also be helpful in determining why the request failed.
|
||||
|
||||
If you are using {@link ng.$templateCache} to pre-load templates, ensure that the cache was
|
||||
populated with the template.
|
||||
@@ -1,25 +0,0 @@
|
||||
@ngdoc error
|
||||
@name $timeout:badprom
|
||||
@fullName Non-$timeout promise
|
||||
@description
|
||||
|
||||
This error occurs when calling {@link ng.$timeout#cancel $timeout.cancel()} with a promise that
|
||||
was not generated by the {@link ng.$timeout $timeout} service. This can, for example, happen when
|
||||
calling {@link ng.$q#the-promise-api then()/catch()} on the returned promise, which creates a new
|
||||
promise, and pass that new promise to {@link ng.$timeout#cancel $timeout.cancel()}.
|
||||
|
||||
Example of incorrect usage that leads to this error:
|
||||
|
||||
```js
|
||||
var promise = $timeout(doSomething, 1000).then(doSomethingElse);
|
||||
$timeout.cancel(promise);
|
||||
```
|
||||
|
||||
To fix the example above, keep a reference to the promise returned by
|
||||
{@link ng.$timeout $timeout()} and pass that to {@link ng.$timeout#cancel $timeout.cancel()}:
|
||||
|
||||
```js
|
||||
var promise = $timeout(doSomething, 1000);
|
||||
var newPromise = promise.then(doSomethingElse);
|
||||
$timeout.cancel(promise);
|
||||
```
|
||||
@@ -3,9 +3,9 @@
|
||||
@fullName Unsupported Selector Lookup
|
||||
@description
|
||||
|
||||
In order to keep AngularJS small, AngularJS implements only a subset of the selectors in {@link angular.element#angularjs-s-jqlite jqLite}.
|
||||
In order to keep Angular small, Angular implements only a subset of the selectors in {@link angular.element#angular-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.
|
||||
|
||||
Alternatively, you can include a full version of jQuery, which AngularJS will automatically use and that will make all selectors available.
|
||||
Alternatively, you can include a full version of jQuery, which Angular will automatically use and that will make all selectors available.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@fullName Testability Not Found
|
||||
@description
|
||||
|
||||
AngularJS's testability helper, getTestability, requires a root element to be
|
||||
passed in. This helps differentiate between different AngularJS apps on the same
|
||||
Angular's testability helper, getTestability, requires a root element to be
|
||||
passed in. This helps differentiate between different Angular 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.
|
||||
|
||||
@@ -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.
|
||||
AngularJS does not set validation errors on the `<input>` in this case
|
||||
Angular 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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
AngularJS does not set validation errors on the `<input>` in this case
|
||||
Angular 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
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ngRef:noctrl
|
||||
@fullName A controller for the value of `ngRefRead` could not be found on the element.
|
||||
@description
|
||||
|
||||
This error occurs when the {@link ng.ngRef ngRef directive} specifies
|
||||
a value in `ngRefRead` that cannot be resolved to a directive / component controller.
|
||||
|
||||
Causes for this error can be:
|
||||
|
||||
1. Your `ngRefRead` value has a typo.
|
||||
2. You have a typo in the *registered* directive / component name.
|
||||
3. The directive / component does not have a controller.
|
||||
|
||||
Note that `ngRefRead` takes the name of the component / directive, not the name of controller, and
|
||||
also not the combination of directive and 'Controller'. For example, for a directive called 'myDirective',
|
||||
the correct declaration is `<div ng-ref="$ctrl.ref" ng-ref-read="myDirective">`.
|
||||
@@ -1,27 +0,0 @@
|
||||
@ngdoc error
|
||||
@name ngRef:nonassign
|
||||
@fullName Non-Assignable Expression
|
||||
@description
|
||||
|
||||
This error occurs when ngRef defines an expression that is not-assignable.
|
||||
|
||||
In order for ngRef to work, it must be possible to write the reference into the path defined with the expression.
|
||||
|
||||
For example, the following expressions are non-assignable:
|
||||
|
||||
```
|
||||
<my-directive ng-ref="{}"></my-directive>
|
||||
|
||||
<my-directive ng-ref="myFn()"></my-directive>
|
||||
|
||||
<!-- missing attribute value is also invalid -->
|
||||
<my-directive ng-ref></my-directive>
|
||||
|
||||
```
|
||||
|
||||
To resolve this error, use a path expression that is assignable:
|
||||
|
||||
```
|
||||
<my-directive ng-ref="$ctrl.reference"></my-directive>
|
||||
|
||||
```
|
||||
@@ -3,7 +3,7 @@
|
||||
@sortOrder 500
|
||||
@description
|
||||
|
||||
# Using the `$location` service
|
||||
# What does it do?
|
||||
|
||||
The `$location` service parses the URL in the browser address bar (based on [`window.location`](https://developer.mozilla.org/en/window.location)) and makes the URL available to
|
||||
your application. Changes to the URL in the address bar are reflected into the `$location` service and
|
||||
@@ -48,7 +48,7 @@ changes to `$location` are reflected into the browser address bar.
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="head">integration with AngularJS application life-cycle</td>
|
||||
<td class="head">integration with angular 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>
|
||||
@@ -76,7 +76,7 @@ the current URL in the browser.
|
||||
It does not cause a full page reload when the browser URL is changed. To reload the page after
|
||||
changing the URL, use the lower-level API, `$window.location.href`.
|
||||
|
||||
## General overview of the API
|
||||
# General overview of the API
|
||||
|
||||
The `$location` service can behave differently, depending on the configuration that was provided to
|
||||
it when it was instantiated. The default configuration is suitable for many applications, for
|
||||
@@ -85,7 +85,7 @@ others customizing the configuration can enable new features.
|
||||
Once the `$location` service is instantiated, you can interact with it via jQuery-style getter and
|
||||
setter methods that allow you to get or change the current URL in the browser.
|
||||
|
||||
### `$location` service configuration
|
||||
## `$location` service configuration
|
||||
|
||||
To configure the `$location` service, retrieve the
|
||||
{@link ng.$locationProvider $locationProvider} and set the parameters as follows:
|
||||
@@ -113,12 +113,12 @@ To configure the `$location` service, retrieve the
|
||||
Prefix used for Hashbang URLs (used in Hashbang mode or in legacy browsers in HTML5 mode).<br />
|
||||
Default: `'!'`
|
||||
|
||||
#### Example configuration
|
||||
### Example configuration
|
||||
```js
|
||||
$locationProvider.html5Mode(true).hashPrefix('*');
|
||||
```
|
||||
|
||||
### Getter and setter methods
|
||||
## Getter and setter methods
|
||||
|
||||
`$location` service provides getter methods for read-only parts of the URL (absUrl, protocol, host,
|
||||
port) and getter / setter methods for url, path, search, hash:
|
||||
@@ -137,7 +137,7 @@ change multiple segments in one go, chain setters like this:
|
||||
$location.path('/newValue').search({key: value});
|
||||
```
|
||||
|
||||
### Replace method
|
||||
## Replace method
|
||||
|
||||
There is a special `replace` method which can be used to tell the $location service that the next
|
||||
time the $location service is synced with the browser, the last history record should be replaced
|
||||
@@ -173,7 +173,7 @@ encoded.
|
||||
`/path?search=a&b=c#hash`. The segments are encoded as well.
|
||||
|
||||
|
||||
## Hashbang and HTML5 Modes
|
||||
# Hashbang and HTML5 Modes
|
||||
|
||||
`$location` service has two configuration modes which control the format of the URL in the browser
|
||||
address bar: **Hashbang mode** (the default) and the **HTML5 mode** which is based on using the
|
||||
@@ -221,15 +221,15 @@ facilitate the browser URL change and history management.
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
### Hashbang mode (default mode)
|
||||
## Hashbang mode (default mode)
|
||||
|
||||
In this mode, `$location` uses Hashbang URLs in all browsers.
|
||||
AngularJS also does not intercept and rewrite links in this mode. I.e. links work
|
||||
Angular 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.
|
||||
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
```js
|
||||
it('should show example', function() {
|
||||
@@ -255,7 +255,7 @@ it('should show example', function() {
|
||||
});
|
||||
```
|
||||
|
||||
### HTML5 mode
|
||||
## HTML5 mode
|
||||
|
||||
In HTML5 mode, the `$location` service getters and setters interact with the browser URL address
|
||||
through the HTML5 history API. This allows for use of regular URL path and search segments,
|
||||
@@ -267,11 +267,11 @@ 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, AngularJS intercepts all links (subject to the "Html link rewriting" rules below)
|
||||
Note that in this mode, Angular 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.
|
||||
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
```js
|
||||
it('should show example', function() {
|
||||
@@ -320,14 +320,14 @@ it('should show example (when browser doesn\'t support HTML5 mode', function() {
|
||||
});
|
||||
```
|
||||
|
||||
#### Fallback for legacy browsers
|
||||
### Fallback for legacy browsers
|
||||
|
||||
For browsers that support the HTML5 history API, `$location` uses the HTML5 history API to write
|
||||
path and search. If the history API is not supported by a browser, `$location` supplies a Hashbang
|
||||
URL. This frees you from having to worry about whether the browser viewing your app supports the
|
||||
history API or not; the `$location` service makes this transparent to you.
|
||||
|
||||
#### HTML link rewriting
|
||||
### HTML link rewriting
|
||||
|
||||
When you use HTML5 history API mode, you will not need special hashbang links. All you have to do
|
||||
is specify regular URL links, such as: `<a href="/some?foo=bar">link</a>`
|
||||
@@ -361,9 +361,9 @@ Note that [attribute name normalization](guide/directive#normalization) does not
|
||||
`'internalLink'` will **not** match `'internal-link'`.
|
||||
|
||||
|
||||
#### Relative links
|
||||
### Relative links
|
||||
|
||||
Be sure to check all relative links, images, scripts etc. AngularJS requires you to specify the url
|
||||
Be sure to check all relative links, images, scripts etc. Angular 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
|
||||
@@ -374,14 +374,14 @@ will only change `$location.hash()` and not modify the url otherwise. This is us
|
||||
to anchors on the same page without needing to know on which page the user currently is.
|
||||
|
||||
|
||||
#### Server side
|
||||
### Server side
|
||||
|
||||
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 AngularJS to differentiate between the part of the url that is the application
|
||||
this case, as it allows Angular 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
|
||||
### Base href constraints
|
||||
|
||||
The `$location` service is not able to function properly if the current URL is outside the URL given
|
||||
as the base href. This can have subtle confusing consequences...
|
||||
@@ -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
|
||||
your server is setup to redirect such requests to `/base/`.
|
||||
you server is setup to redirect such requests to `/base/`.
|
||||
|
||||
See https://github.com/angular/angular.js/issues/14018 for more information.
|
||||
|
||||
@@ -403,7 +403,7 @@ legacy browsers and hashbang links in modern browser:
|
||||
- Modern browser will rewrite hashbang URLs to regular URLs.
|
||||
- Older browsers will redirect regular URLs to hashbang URLs.
|
||||
|
||||
#### Example
|
||||
### Example
|
||||
|
||||
Here you can see two `$location` instances that show the difference between **Html5 mode** and **Html5 Fallback mode**.
|
||||
Note that to simulate different levels of browser support, the `$location` instances are connected to
|
||||
@@ -415,7 +415,7 @@ redirect to regular / hashbang url, as this conversion happens only during parsi
|
||||
|
||||
In these examples we use `<base href="/base/index.html" />`. The inputs represent the address bar of the browser.
|
||||
|
||||
##### Browser in HTML5 mode
|
||||
#### Browser in HTML5 mode
|
||||
<example module="html5-mode" name="location-html5-mode">
|
||||
<file name="index.html">
|
||||
<div ng-controller="LocationController">
|
||||
@@ -565,7 +565,7 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
|
||||
</example>
|
||||
|
||||
##### Browser in HTML5 Fallback mode (Hashbang mode)
|
||||
#### Browser in HTML5 Fallback mode (Hashbang mode)
|
||||
<example module="hashbang-mode" name="location-hashbang-mode">
|
||||
<file name="index.html">
|
||||
<div ng-controller="LocationController">
|
||||
@@ -718,27 +718,27 @@ In these examples we use `<base href="/base/index.html" />`. The inputs represen
|
||||
|
||||
</example>
|
||||
|
||||
## Caveats
|
||||
# Caveats
|
||||
|
||||
### Page reload navigation
|
||||
## Page reload navigation
|
||||
|
||||
The `$location` service allows you to change only the URL; it does not allow you to reload the
|
||||
page. When you need to change the URL and reload the page or navigate to a different page, please
|
||||
use a lower level API, {@link ng.$window $window.location.href}.
|
||||
|
||||
### Using $location outside of the scope life-cycle
|
||||
## Using $location outside of the scope life-cycle
|
||||
|
||||
`$location` knows about AngularJS's {@link ng.$rootScope.Scope scope} life-cycle. When a URL changes in
|
||||
`$location` knows about Angular'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 AngularJS (for example, through a DOM Event or
|
||||
When you want to change the `$location` from outside Angular (for example, through a DOM Event or
|
||||
during testing) - you must call `$apply` to propagate the changes.
|
||||
|
||||
### $location.path() and ! or / prefixes
|
||||
## $location.path() and ! or / prefixes
|
||||
|
||||
A path should always begin with forward slash (`/`); the `$location.path()` setter will add the
|
||||
forward slash if it is missing.
|
||||
@@ -746,17 +746,22 @@ forward slash if it is missing.
|
||||
Note that the `!` prefix in the hashbang mode is not part of `$location.path()`; it is actually
|
||||
`hashPrefix`.
|
||||
|
||||
### Crawling your app
|
||||
## Crawling your app
|
||||
|
||||
Most modern search engines are able to crawl AJAX applications with dynamic content, provided all
|
||||
included resources are available to the crawler bots.
|
||||
To allow indexing of your AJAX application, you have to add special meta tag in the head section of
|
||||
your document:
|
||||
|
||||
There also exists a special
|
||||
[AJAX crawling scheme](http://code.google.com/web/ajaxcrawling/docs/specification.html) developed by
|
||||
Google that allows bots to crawl the static equivalent of a dynamically generated page,
|
||||
but this schema has been deprecated, and support for it may vary by search engine.
|
||||
```html
|
||||
<meta name="fragment" content="!" />
|
||||
```
|
||||
|
||||
## Testing with the $location service
|
||||
This will cause crawler bot to request links with `_escaped_fragment_` param so that your server
|
||||
can recognize the crawler and serve a HTML snapshots. For more information about this technique,
|
||||
see [Making AJAX Applications
|
||||
Crawlable](http://code.google.com/web/ajaxcrawling/docs/specification.html).
|
||||
|
||||
|
||||
# Testing with the $location service
|
||||
|
||||
When using `$location` service during testing, you are outside of the angular's {@link
|
||||
ng.$rootScope.Scope scope} life-cycle. This means it's your responsibility to call `scope.$apply()`.
|
||||
@@ -779,6 +784,85 @@ describe('serviceUnderTest', function() {
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
# Migrating from earlier AngularJS releases
|
||||
|
||||
In earlier releases of Angular, `$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.
|
||||
|
||||
## Changes to your code
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr class="head">
|
||||
<th>Navigation inside the app</th>
|
||||
<th>Change to</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>$location.href = value<br />$location.hash = value<br />$location.update(value)<br
|
||||
/>$location.updateHash(value)</td>
|
||||
<td>$location.path(path).search(search)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.hashPath = path</td>
|
||||
<td>$location.path(path)</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.hashSearch = search</td>
|
||||
<td>$location.search(search)</td>
|
||||
</tr>
|
||||
|
||||
<tr class="head">
|
||||
<th>Navigation outside the app</td>
|
||||
<th>Use lower level API</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.href = value<br />$location.update(value)</td>
|
||||
<td>$window.location.href = value</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location[protocol | host | port | path | search]</td>
|
||||
<td>$window.location[protocol | host | port | path | search]</td>
|
||||
</tr>
|
||||
|
||||
<tr class="head">
|
||||
<th>Read access</td>
|
||||
<th>Change to</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.hashPath</td>
|
||||
<td>$location.path()</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.hashSearch</td>
|
||||
<td>$location.search()</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.href<br />$location.protocol<br />$location.host<br />$location.port<br
|
||||
/>$location.hash</td>
|
||||
<td>$location.absUrl()<br />$location.protocol()<br />$location.host()<br />$location.port()<br
|
||||
/>$location.path() + $location.search()</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>$location.path<br />$location.search</td>
|
||||
<td>$window.location.path<br />$window.location.search</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## Two-way binding to $location
|
||||
|
||||
Because `$location` uses getters/setters, you can use `ng-model-options="{ getterSetter: true }"`
|
||||
@@ -800,6 +884,6 @@ angular.module('locationExample', [])
|
||||
</file>
|
||||
</example>
|
||||
|
||||
## Related API
|
||||
# Related API
|
||||
|
||||
* {@link ng.$location `$location` API}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
# Accessibility with ngAria
|
||||
|
||||
The goal of ngAria is to improve AngularJS's default accessibility by enabling common
|
||||
The goal of ngAria is to improve Angular'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 AngularJS.
|
||||
Accessibility best practices that apply to web apps in general also apply to Angular.
|
||||
|
||||
* **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
|
||||
|
||||
@@ -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 an HTML element within your application, you can apply animations to it. Let's say for
|
||||
attached to a HTML element within your application, you can apply animations to it. Lets say for
|
||||
example that we have an HTML template with a repeater like so:
|
||||
|
||||
```html
|
||||
@@ -222,26 +222,22 @@ triggered:
|
||||
|
||||
| Directive | Supported Animations |
|
||||
|-------------------------------------------------------------------------------|---------------------------------------------------------------------------|
|
||||
| {@link ng.directive:form#animations form / ngForm} | add and remove ({@link ng.directive:form#css-classes various classes}) |
|
||||
| {@link ngAnimate.directive:ngAnimateSwap#animations ngAnimateSwap} | enter and leave |
|
||||
| {@link ng.directive:ngClass#animations ngClass / {{class}​}} | 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:ngIf#animations ngIf} | enter and leave |
|
||||
| {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
|
||||
| {@link module:ngMessages#animations ngMessage / ngMessageExp} | enter and leave |
|
||||
| {@link module:ngMessages#animations ngMessages} | add and remove (the `ng-active`/`ng-inactive` classes) |
|
||||
| {@link ng.directive:ngModel#animations ngModel} | add and remove ({@link ng.directive:ngModel#css-classes various classes}) |
|
||||
| {@link ng.directive:ngRepeat#animations ngRepeat} | enter, leave, and move |
|
||||
| {@link ng.directive:ngShow#animations ngShow} | add and remove (the `ng-hide` class) |
|
||||
| {@link ng.directive:ngIf#animations ngIf} | enter and leave |
|
||||
| {@link ng.directive:ngSwitch#animations ngSwitch} | enter and leave |
|
||||
| {@link ng.directive:ngInclude#animations ngInclude} | enter and leave |
|
||||
| {@link ngRoute.directive:ngView#animations ngView} | enter and leave |
|
||||
|
||||
(More information can be found by visiting the documentation associated with each directive.)
|
||||
| {@link module:ngMessages#animations ngMessage / ngMessageExp} | enter and leave |
|
||||
| {@link ng.directive:ngClass#animations ngClass / {{class}​}} | add and remove |
|
||||
| {@link ng.directive:ngClass#animations ngClassEven / 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 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
|
||||
{@link ng.$animate `$animate` API docs}.
|
||||
{@link ng.$animate API docs}.
|
||||
|
||||
## How do I use animations in my own directives?
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
# Bootstrap
|
||||
|
||||
This page explains the AngularJS initialization process and how you can manually initialize AngularJS
|
||||
This page explains the Angular initialization process and how you can manually initialize Angular
|
||||
if necessary.
|
||||
|
||||
|
||||
## AngularJS `<script>` Tag
|
||||
## Angular `<script>` Tag
|
||||
|
||||
This example shows the recommended path for integrating AngularJS with what we call automatic
|
||||
This example shows the recommended path for integrating Angular 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
|
||||
AngularJS to auto-bootstrap your application.
|
||||
angular 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">
|
||||
|
||||
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
|
||||
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
|
||||
for the {@link ng.directive:ngApp `ngApp`} directive which designates your application root.
|
||||
If the {@link ng.directive:ngApp `ngApp`} directive is found then AngularJS will:
|
||||
If the {@link ng.directive:ngApp `ngApp`} directive is found then Angular 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 AngularJS application.
|
||||
portion of the DOM as an Angular 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 AngularJS compiles a page.
|
||||
or the need to perform an operation before Angular compiles a page.
|
||||
|
||||
Here is an example of manually initializing AngularJS:
|
||||
Here is an example of manually initializing Angular:
|
||||
|
||||
```html
|
||||
<!doctype html>
|
||||
|
||||
@@ -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 AngularJS's compilation process, you're in the right place.
|
||||
If you want a deeper look into Angular's compilation process, you're in the right place.
|
||||
</div>
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
AngularJS's {@link ng.$compile HTML compiler} allows the developer to teach the
|
||||
Angular'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. AngularJS calls these behavior
|
||||
and even create new HTML elements or attributes with custom behavior. Angular 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.
|
||||
|
||||
AngularJS comes pre-bundled with common directives which are useful for building any app. We also
|
||||
Angular 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 AngularJS service which traverses the DOM looking for attributes. The compilation
|
||||
Compiler is an Angular 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
|
||||
|
||||
AngularJS is different. The AngularJS compiler consumes the DOM, not string templates.
|
||||
Angular is different. The Angular 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, AngularJS directives can contain not just text bindings, but behavioral constructs as
|
||||
Furthermore, Angular directives can contain not just text bindings, but behavioral constructs as
|
||||
well.
|
||||
|
||||
<img src="img/Two_Way_Data_Binding.png">
|
||||
|
||||
The AngularJS approach produces a stable DOM. The DOM element instance bound to a model
|
||||
The Angular 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 AngularJS operates on DOM nodes rather than strings. Usually, you don't
|
||||
It's important to note that Angular 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 AngularJS does internally.
|
||||
This should help give you an idea of what Angular does internally.
|
||||
|
||||
```js
|
||||
var $compile = ...; // injected into your code
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
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 Component Router for AngularJS.
|
||||
This guide describes the new Component Router for AngularJS 1.5.
|
||||
|
||||
<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.
|
||||
@@ -28,7 +28,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 AngularJS component with a RouteConfig and an associated Router. |
|
||||
| Routing Component | An Angular 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 +138,7 @@ The result is that we end up with a hierarchy of **Routing Components** rendered
|
||||

|
||||
|
||||
|
||||
## Example Heroes App
|
||||
# Example Heroes App
|
||||
|
||||
You can see the complete application running below.
|
||||
|
||||
@@ -459,12 +459,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 +475,9 @@ yarn add angular@1.5.x @angular/router@0.2.0
|
||||
```
|
||||
|
||||
|
||||
#### Load the scripts
|
||||
## Load the scripts
|
||||
|
||||
Just like any AngularJS application, we load the JavaScript files into our `index.html`:
|
||||
Just like any Angular application, we load the JavaScript files into our `index.html`:
|
||||
|
||||
```html
|
||||
<script src="/node_modules/angular/angular.js"></script>
|
||||
@@ -494,7 +494,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 +528,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 AngularJS {@link $compileProvider#component `.component()`} helper method to create
|
||||
We are using the Angular 1.5 {@link $compileProvider#component `.component()`} helper method to create
|
||||
all the **Components** in our application. It is perfectly suited to this task.
|
||||
|
||||
```js
|
||||
@@ -547,9 +547,9 @@ must have a base URL.
|
||||
...
|
||||
```
|
||||
|
||||
#### Bootstrap AngularJS
|
||||
## Bootstrap AngularJS
|
||||
|
||||
Bootstrap the AngularJS application and add the top level App Component.
|
||||
Bootstrap the Angular application and add the top level App Component.
|
||||
|
||||
```html
|
||||
<body ng-app="app">
|
||||
@@ -559,7 +559,7 @@ Bootstrap the AngularJS 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 +577,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 +598,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 +607,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 +616,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 AngularJS module for the **Components** of this feature
|
||||
Create a new file `heroes.js`, which defines a new Angular module for the **Components** of this feature
|
||||
and registers the Heroes **Component**.
|
||||
|
||||
```js
|
||||
@@ -651,20 +651,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 +676,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 +705,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 +735,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 +780,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 +811,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 the new Angular, we cannot use the dependency injector to get hold of a component's Router.
|
||||
Each component has its own Router. Unlike in Angular 2, 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 +882,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 +894,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 +936,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 +951,7 @@ changes to the crisis being edited.
|
||||

|
||||
|
||||
|
||||
### Crisis Feature
|
||||
## Crisis Feature
|
||||
|
||||
This feature is very similar to the Heroes feature. It contains the following **Components**:
|
||||
|
||||
@@ -962,7 +962,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 +979,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.
|
||||
|
||||
@@ -5,17 +5,17 @@
|
||||
|
||||
# Understanding Components
|
||||
|
||||
In AngularJS, a Component is a special kind of {@link guide/directive directive} that uses a simpler
|
||||
In Angular, 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 the new Angular'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 Angular
|
||||
2'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
|
||||
- writing component directives will make it easier to upgrade to Angular 2
|
||||
|
||||
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 {@link ng.$compileProvider#component `.component()`} method of an AngularJS module (returned by {@link module `angular.module()`}). The method takes two arguments:
|
||||
Components can be registered using the `.component()` method of an Angular 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 AngularJS
|
||||
Components should never modify any data or DOM that is out of their own scope. Normally, in Angular
|
||||
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 AngularJS uses two-way binding. So if you pass
|
||||
However, scope isolation only goes so far, because Angular 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,
|
||||
@@ -143,7 +143,7 @@ components should follow a few simple conventions:
|
||||
}
|
||||
```
|
||||
|
||||
- **Components have a well-defined lifecycle:**
|
||||
- **Components have a well-defined lifecycle**
|
||||
Each component can implement "lifecycle hooks". These are methods that will be called at certain points in the life
|
||||
of the component. The following hook methods can be implemented:
|
||||
|
||||
@@ -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 AngularJS's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
|
||||
be detected by Angular'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.
|
||||
Since the compilation process is rather different in AngularJS there is no direct mapping and care should
|
||||
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
|
||||
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
|
||||
|
||||
@@ -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 AngularJS, a file like this is called a
|
||||
<a name="template">{@link templates template}</a>. When AngularJS starts your application, it parses and
|
||||
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
|
||||
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. AngularJS also defines a directive for the {@link ng.directive:input `input`}
|
||||
initializes our application. Angular 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 AngularJS, the only place where an application should access the DOM is
|
||||
**Custom directives to access the DOM**: In Angular, 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
|
||||
AngularJS to read and write variables. Note that those variables are not global variables.
|
||||
Angular to read and write variables. Note that those variables are not global variables.
|
||||
Just like variables in a JavaScript function live in a scope,
|
||||
AngularJS provides a <a name="scope">{@link scope scope}</a> for the variables accessible to expressions.
|
||||
Angular 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 AngularJS to "take the data we got from the input widgets
|
||||
Applied to the example above, the markup directs Angular 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 AngularJS provides _live_ bindings:
|
||||
The important thing in the example is that Angular 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 AngularJS that the new `InvoiceController` is responsible for the element with the directive
|
||||
This directive tells Angular 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 AngularJS to instantiate the controller
|
||||
The syntax `InvoiceController as invoice` tells Angular 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 AngularJS (directives, filters, controllers,
|
||||
services, ...) is created and wired using dependency injection. Within AngularJS,
|
||||
Everything within Angular (directives, filters, controllers,
|
||||
services, ...) is created and wired using dependency injection. Within Angular,
|
||||
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 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,
|
||||
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,
|
||||
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 AngularJS
|
||||
The template contains the directive `ng-app="invoice2"`. This tells Angular
|
||||
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, AngularJS uses the `InvoiceController` as well as the `currencyConverter` service.
|
||||
`finance2` module. By this, Angular uses the `InvoiceController` as well as the `currencyConverter` service.
|
||||
|
||||
Now that AngularJS knows of all the parts of the application, it needs to create them.
|
||||
Now that Angular 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 AngularJS, this is done by simply defining arguments on the constructor function. With this, the injector
|
||||
In Angular, 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, AngularJS knows about the
|
||||
In our example, the `InvoiceController` has an argument named `currencyConverter`. By this, Angular 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.
|
||||
AngularJS uses this array syntax to define the dependencies so that the DI also works after minifying
|
||||
Angular 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 AngularJS:
|
||||
The following example shows how this is done with Angular:
|
||||
|
||||
<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 AngularJS:
|
||||
|
||||
What changed?
|
||||
Our `currencyConverter` service of the `finance` module now uses the {@link ng.$http `$http`}, a
|
||||
built-in service provided by AngularJS for accessing a server backend. `$http` is a wrapper around
|
||||
built-in service provided by Angular 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.
|
||||
|
||||
|
||||
@@ -5,21 +5,16 @@
|
||||
|
||||
# Understanding Controllers
|
||||
|
||||
In AngularJS, a Controller is defined by a JavaScript **constructor function** that is used to augment the
|
||||
{@link scope AngularJS Scope}.
|
||||
In Angular, a Controller is defined by a JavaScript **constructor function** that is used to augment the
|
||||
{@link scope Angular 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}.
|
||||
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`.
|
||||
|
||||
If the controller has been attached using the `controller as` syntax then the controller instance will
|
||||
be assigned to a property on the scope.
|
||||
be assigned to a property on the new scope.
|
||||
|
||||
Use controllers to:
|
||||
|
||||
@@ -29,27 +24,18 @@ 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. AngularJS
|
||||
Putting any presentation logic into Controllers significantly affects its testability. Angular
|
||||
has {@link databinding databinding} for most cases and {@link guide/directive directives} to
|
||||
encapsulate manual DOM manipulation.
|
||||
- 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
|
||||
- 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
|
||||
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 AngularJS
|
||||
Typically, when you create an application you need to set up the initial state for the Angular
|
||||
`$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
|
||||
@@ -66,13 +52,13 @@ myApp.controller('GreetingController', ['$scope', function($scope) {
|
||||
}]);
|
||||
```
|
||||
|
||||
We create an {@link module AngularJS Module}, `myApp`, for our application. Then we add the controller's
|
||||
We create an {@link module Angular 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 AngularJS. See the guide on
|
||||
of the Controller on the `$scope` service provided by Angular. See the guide on
|
||||
{@link guide/di Dependency Injection} for more information.
|
||||
</div>
|
||||
|
||||
@@ -102,7 +88,7 @@ myApp.controller('DoubleController', ['$scope', function($scope) {
|
||||
}]);
|
||||
```
|
||||
|
||||
Once the Controller has been attached to the DOM, the `double` method can be invoked in an AngularJS
|
||||
Once the Controller has been attached to the DOM, the `double` method can be invoked in an Angular
|
||||
expression in the template:
|
||||
|
||||
```js
|
||||
@@ -113,12 +99,29 @@ 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 AngularJS expressions
|
||||
the scope are available in the template/view, and can be invoked via angular 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 AngularJS, let's create a little app with the
|
||||
To illustrate further how Controller components work in Angular, let's create a little app with the
|
||||
following components:
|
||||
|
||||
- A {@link templates template} with two buttons and a simple message
|
||||
@@ -259,7 +262,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}:
|
||||
|
||||
@@ -4,38 +4,38 @@
|
||||
@description
|
||||
|
||||
|
||||
AngularJS sets these CSS classes. It is up to your application to provide useful styling.
|
||||
Angular sets these CSS classes. It is up to your application to provide useful styling.
|
||||
|
||||
# CSS classes used by AngularJS
|
||||
# CSS classes used by angular
|
||||
|
||||
* `ng-scope`
|
||||
- **Usage:** AngularJS applies this class to any element for which a new {@link $rootScope scope}
|
||||
- **Usage:** angular 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:** AngularJS applies this class to any element for which a new
|
||||
- **Usage:** angular 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:** AngularJS applies this class to any element that is attached to a data binding, via `ng-bind` or
|
||||
- **Usage:** angular 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:** AngularJS applies this class to a form control widget element if that element's input does
|
||||
- **Usage:** angular 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:** AngularJS {@link ng.directive:ngModel ngModel} directive applies `ng-pristine` class
|
||||
- **Usage:** angular {@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:** AngularJS {@link ng.directive:ngModel ngModel} directive applies `ng-untouched` class
|
||||
- **Usage:** angular {@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 AngularJS Templates}
|
||||
* {@link guide/forms AngularJS Forms}
|
||||
* {@link guide/templates Angular Templates}
|
||||
* {@link guide/forms Angular Forms}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
# Data Binding
|
||||
|
||||
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
|
||||
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
|
||||
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 AngularJS Templates
|
||||
## Data Binding in Angular Templates
|
||||
|
||||
<img class="right" src="img/Two_Way_Data_Binding.png"/><br />
|
||||
AngularJS templates work differently. First the template (which is the uncompiled HTML along with
|
||||
Angular 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 AngularJS Scopes}
|
||||
* {@link templates AngularJS Templates}
|
||||
* {@link scope Angular Scopes}
|
||||
* {@link templates Angular Templates}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user