Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 47a55ca767 | |||
| 3d78bf3fa8 | |||
| 6e80d0ad54 | |||
| ae637acdfb | |||
| 661f6d9ecf | |||
| 56a7abd38f | |||
| 7d70dcdab1 | |||
| 9e6161e579 | |||
| bd28c74c1d | |||
| cd77c089ba | |||
| 83f88c1818 | |||
| fb2c585897 | |||
| bdbe4fd34a | |||
| 0b4e150aa5 | |||
| e091bb7dbb | |||
| b62c858499 | |||
| 4a18274670 | |||
| e3bf1ed217 | |||
| a5f037d033 | |||
| 25152bb218 | |||
| 24eb528b05 | |||
| d161cc6b25 | |||
| d604f941e8 | |||
| 85758ce3af | |||
| 924e68c7d5 | |||
| f297aa5d0a | |||
| 337ce67612 | |||
| 8b56c08327 | |||
| 32eec67023 | |||
| fd1528a6c8 | |||
| 6cb5fbf5ef | |||
| f6644c720e | |||
| 0d9aafba3b |
+129
-2
@@ -1,3 +1,102 @@
|
||||
<a name="1.3.8"></a>
|
||||
# 1.3.8 prophetic-narwhal (2014-12-19)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
- **filterFilter:**
|
||||
- make `$` match properties on deeper levels as well
|
||||
([bd28c74c](https://github.com/angular/angular.js/commit/bd28c74c1d91c477a86f10fe36576cba0249e6ef),
|
||||
[#10401](https://github.com/angular/angular.js/issues/10401))
|
||||
- let expression object `{$: '...'}` also match primitive items
|
||||
([fb2c5858](https://github.com/angular/angular.js/commit/fb2c58589758744c0eef8c2ead3dbcf27a5cf200),
|
||||
[#10428](https://github.com/angular/angular.js/issues/10428))
|
||||
- **ngAria:** trigger digest on `ng-click` via keypress, pass `$event` to expression
|
||||
([924e68c7](https://github.com/angular/angular.js/commit/924e68c7d522a1086969f3583d0ce87e59110bc5),
|
||||
[#10442](https://github.com/angular/angular.js/issues/10442), [#10443](https://github.com/angular/angular.js/issues/10443), [#10447](https://github.com/angular/angular.js/issues/10447))
|
||||
- **orderBy:** compare timestamps when sorting date objects
|
||||
([661f6d9e](https://github.com/angular/angular.js/commit/661f6d9ecf1459ce3b2794c3cde373e17ae83972),
|
||||
[#10512](https://github.com/angular/angular.js/issues/10512), [#10516](https://github.com/angular/angular.js/issues/10516))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **limitTo:** replace for loop with slice
|
||||
([cd77c089](https://github.com/angular/angular.js/commit/cd77c089ba2f4b94ccc74f32f0ffa9fb70851c02))
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="1.3.7"></a>
|
||||
# 1.3.7 leaky-obstruction (2014-12-15)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$compile:** use `createMap()` for `$$observe` listeners when initialized from attr interpolation
|
||||
([8e28bb4c](https://github.com/angular/angular.js/commit/8e28bb4c2f6d015dfe1cec7755f1ca9b0ecef1f8))
|
||||
- **$http:**
|
||||
- only parse as JSON when opening/closing brackets match
|
||||
([b9bdbe61](https://github.com/angular/angular.js/commit/b9bdbe615cc4070d2233ff06830a4c6fb1217cda),
|
||||
[#10349](https://github.com/angular/angular.js/issues/10349), [#10357](https://github.com/angular/angular.js/issues/10357))
|
||||
- don't convert FormData objects to JSON
|
||||
([40258838](https://github.com/angular/angular.js/commit/40258838031604feecb862afdc6f1f503d80ce4a),
|
||||
[#10373](https://github.com/angular/angular.js/issues/10373))
|
||||
- **$parse:** a chain of field accessors should use a single `getterFn`
|
||||
([c90ad968](https://github.com/angular/angular.js/commit/c90ad96808be350526516626205c3a7d1da79024))
|
||||
- **ngRepeat:** allow extra whitespaces in `(key,value)` part of micro-syntax
|
||||
([ef640cbc](https://github.com/angular/angular.js/commit/ef640cbc2af5794c987e75472c12e63a59590044),
|
||||
[#6827](https://github.com/angular/angular.js/issues/6827), [#6833](https://github.com/angular/angular.js/issues/6833))
|
||||
- **orderBy:** do not try to call `valueOf`/`toString` on `null`
|
||||
([a097aa95](https://github.com/angular/angular.js/commit/a097aa95b7c78beab6d1b7d521c25f7d9d7843d9),
|
||||
[#10385](https://github.com/angular/angular.js/issues/10385), [#10386](https://github.com/angular/angular.js/issues/10386))
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **$compile:** add support for `ng-attr` with camelCased attributes
|
||||
([d8e37078](https://github.com/angular/angular.js/commit/d8e37078600089839f82f0e84022f1087e1fd3f2),
|
||||
[#9845](https://github.com/angular/angular.js/issues/9845), [#10194](https://github.com/angular/angular.js/issues/10194))
|
||||
- **$http:** pass response status code to data transform functions
|
||||
([1b740974](https://github.com/angular/angular.js/commit/1b740974f5eb373bed04071d51f908ced7c5a8e5),
|
||||
[#10324](https://github.com/angular/angular.js/issues/10324), [#6734](https://github.com/angular/angular.js/issues/6734), [#10440](https://github.com/angular/angular.js/issues/10440))
|
||||
- **$rootScope:** allow passing `locals` argument to `$evalAsync`
|
||||
([9b96cea4](https://github.com/angular/angular.js/commit/9b96cea462676d123e1b2dd852aedbe3da8fa4a0),
|
||||
[#10390](https://github.com/angular/angular.js/issues/10390))
|
||||
|
||||
|
||||
## Performance Improvements
|
||||
|
||||
- **$compile:** only re-`$interpolate` attribute values at link time if changed since compile
|
||||
([9ae0c01c](https://github.com/angular/angular.js/commit/9ae0c01c2bcaff2f3906eec574f9c6ed8abde14a))
|
||||
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- **orderBy:** due to [a097aa95](https://github.com/angular/angular.js/commit/a097aa95b7c78beab6d1b7d521c25f7d9d7843d9),
|
||||
|
||||
Previously, if either value being compared in the orderBy comparator was null or undefined, the
|
||||
order would, incorrectly, not change. Now, this order behaves more like Array.prototype.sort, which
|
||||
by default pushes `null` behind objects, due to `n` occurring after `[` (the first characters of their
|
||||
stringified forms) in ASCII / Unicode. If `toString` is customized, or does not exist, the
|
||||
behaviour is undefined.
|
||||
|
||||
|
||||
|
||||
<a name="1.2.28"></a>
|
||||
# 1.2.28 finnish-disembarkation (2014-12-15)
|
||||
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
- **$route:** fix redirection with optional/eager params
|
||||
([1b9e408d](https://github.com/angular/angular.js/commit/1b9e408ddbe48a6d3db27f501515d6efad01f42d),
|
||||
[#9742](https://github.com/angular/angular.js/issues/9742), [#10202](https://github.com/angular/angular.js/issues/10202))
|
||||
- **linky:** encode double quotes when serializing email addresses
|
||||
([929dd15b](https://github.com/angular/angular.js/commit/929dd15b9b65034350f18abe6c56a8d956f4b978),
|
||||
[#8945](https://github.com/angular/angular.js/issues/8945), [#8964](https://github.com/angular/angular.js/issues/8964), [#5946](https://github.com/angular/angular.js/issues/5946), [#10090](https://github.com/angular/angular.js/issues/10090), [#9256](https://github.com/angular/angular.js/issues/9256))
|
||||
|
||||
|
||||
|
||||
<a name="1.3.6"></a>
|
||||
# 1.3.6 robofunky-danceblaster (2014-12-08)
|
||||
|
||||
@@ -17,7 +116,7 @@
|
||||
- strip off empty hash segments when comparing
|
||||
([e93710fe](https://github.com/angular/angular.js/commit/e93710fe0e4fb05ceee59a04f290692a5bec5d20),
|
||||
[#9635](https://github.com/angular/angular.js/issues/9635))
|
||||
- **$parse:**
|
||||
- **$parse:**
|
||||
- fix operators associativity
|
||||
([ed1243ff](https://github.com/angular/angular.js/commit/ed1243ffc7c2cb4bd5b4dece597597db8eb08e34))
|
||||
- follow JavaScript context for unbound functions
|
||||
@@ -81,7 +180,7 @@
|
||||
## Breaking Changes
|
||||
|
||||
- **$location:** due to [2dc34a96](https://github.com/angular/angular.js/commit/2dc34a969956eea680be4c8d9f800556d110996a),
|
||||
|
||||
|
||||
|
||||
We no longer throw an `ihshprfx` error if the URL after the base path
|
||||
contains only a hash fragment. Previously, if the base URL was `http://abc.com/base/`
|
||||
@@ -96,6 +195,34 @@ and hashPrfix are set up as above, then `http://abc.com/base/other/path` does no
|
||||
throw an error but just ignores the extra path: `http://abc.com/base`.
|
||||
|
||||
|
||||
- **filterFilter:** due to [a75537d4](https://github.com/angular/angular.js/commit/a75537d461c92e3455e372ff5005bf0cad2d2e95),
|
||||
|
||||
Named properties in the expression object will only match against properties on the **same level**.
|
||||
Previously, named string properties would match against properties on the same level **or deeper**.
|
||||
|
||||
Before:
|
||||
|
||||
```js
|
||||
arr = filterFilter([{level1: {level2: 'test'}}], {level1: 'test'}); // arr.length -> 1
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```js
|
||||
arr = filterFilter([{level1: {level2: 'test'}}], {level1: 'test'}); // arr.length -> 0
|
||||
```
|
||||
|
||||
In order to match deeper nested properties, you have to either match the depth level of the
|
||||
property or use the special `$` key (which still matches properties on the same level
|
||||
**or deeper**). E.g.:
|
||||
|
||||
```js
|
||||
// Both examples below have `arr.length === 1`
|
||||
arr = filterFilter([{level1: {level2: 'test'}}], {level1: {level2: 'test'}});
|
||||
arr = filterFilter([{level1: {level2: 'test'}}], {$: 'test'});
|
||||
```
|
||||
|
||||
|
||||
<a name="1.3.5"></a>
|
||||
# 1.3.5 cybernetic-mercantilism (2014-12-01)
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ Use ngRoute to enable URL routing to your application. The ngRoute module suppor
|
||||
|
||||
## {@link ngAnimate ngAnimate}
|
||||
|
||||
Use ngAnimate to enable animation features into your application. Various core ng 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.
|
||||
|
||||
@@ -273,7 +273,7 @@ Use ngSanitize to securely parse and manipulate HTML data in your application.
|
||||
|
||||
## {@link ngMock ngMock}
|
||||
|
||||
Use ngMock to inject and mock modules, factories, services and providers within your unit tests
|
||||
Use ngMock to inject and mock modules, factories, services and providers within your unit tests.
|
||||
|
||||
<div class="alert alert-info">Include the **angular-mocks.js** file into your test runner for this to work.</div>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
@fullName Response does not match configured parameter
|
||||
@description
|
||||
|
||||
This error occurs when the {@link ngResource.$resource `$resource`} service expects a response that can be deserialized as an array, receives an object, or vice versa.
|
||||
This error occurs when the {@link ngResource.$resource `$resource`} service expects a response that can be deserialized as an array but receives an object, or vice versa.
|
||||
By default, all resource actions expect objects, except `query` which expects arrays.
|
||||
|
||||
To resolve this error, make sure your `$resource` configuration matches the actual format of the data returned from the server.
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
@fullName Bad `hasOwnProperty` Name
|
||||
@description
|
||||
|
||||
Occurs when you try to use the name `hasOwnProperty` in a context where it is not allow.
|
||||
Occurs when you try to use the name `hasOwnProperty` in a context where it is not allowed.
|
||||
Generally, a name cannot be `hasOwnProperty` because it is used, internally, on a object
|
||||
and allowing such a name would break lookups on this object.
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
# What does it do?
|
||||
|
||||
The `$location` service parses the URL in the browser address bar (based on the [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 $location service and
|
||||
changes to $location are reflected into the browser address bar.
|
||||
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
|
||||
changes to `$location` are reflected into the browser address bar.
|
||||
|
||||
**The $location service:**
|
||||
|
||||
@@ -21,7 +21,7 @@ changes to $location are reflected into the browser address bar.
|
||||
- Represents the URL object as a set of methods (protocol, host, port, path, search, hash).
|
||||
|
||||
|
||||
## Comparing $location to window.location
|
||||
## Comparing `$location` to `window.location`
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
@@ -68,7 +68,7 @@ changes to $location are reflected into the browser address bar.
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## When should I use $location?
|
||||
## When should I use `$location`?
|
||||
Any time your application needs to react to a change in the current URL or if you want to change
|
||||
the current URL in the browser.
|
||||
|
||||
@@ -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:
|
||||
@@ -835,7 +835,7 @@ angular.module('locationExample', [])
|
||||
|
||||
# Related API
|
||||
|
||||
* {@link ng.$location $location API}
|
||||
* {@link ng.$location `$location` API}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# E2E Testing
|
||||
|
||||
<div class="alert alert-danger">
|
||||
**Note:** In the past, end to end testing could be done with a deprecated tool called
|
||||
**Note:** In the past, end-to-end testing could be done with a deprecated tool called
|
||||
[Angular Scenario Runner](http://code.angularjs.org/1.2.16/docs/guide/e2e-testing). That tool
|
||||
is now in maintenance mode.
|
||||
</div>
|
||||
@@ -14,7 +14,7 @@ is now in maintenance mode.
|
||||
As applications grow in size and complexity, it becomes unrealistic to rely on manual testing to
|
||||
verify the correctness of new features, catch bugs and notice regressions. Unit tests
|
||||
are the first line of defense for catching bugs, but sometimes issues come up with integration
|
||||
between components which can't be captured in a unit test. End to end tests are made to find
|
||||
between components which can't be captured in a unit test. End-to-end tests are made to find
|
||||
these problems.
|
||||
|
||||
We have built [Protractor](https://github.com/angular/protractor), an end
|
||||
@@ -23,7 +23,7 @@ Angular application.
|
||||
|
||||
## Using Protractor
|
||||
|
||||
Protractor is a [Node.js](http://nodejs.org) program, and runs end to end tests that are also
|
||||
Protractor is a [Node.js](http://nodejs.org) program, and runs end-to-end tests that are also
|
||||
written in JavaScript and run with node. Protractor uses [WebDriver](https://code.google.com/p/selenium/wiki/GettingStarted)
|
||||
to control browsers and simulate user actions.
|
||||
|
||||
@@ -77,7 +77,7 @@ filter the list of items.
|
||||
## Example
|
||||
See the [angular-seed](https://github.com/angular/angular-seed) project for more examples, or look
|
||||
at the embedded examples in the Angular documentation (For example, {@link $http $http}
|
||||
has an end to end test in the example under the `protractor.js` tag).
|
||||
has an end-to-end test in the example under the `protractor.js` tag).
|
||||
|
||||
## Caveats
|
||||
|
||||
|
||||
@@ -26,8 +26,16 @@ Angular expressions are like JavaScript expressions with the following differenc
|
||||
* **Forgiving:** In JavaScript, trying to evaluate undefined properties generates `ReferenceError`
|
||||
or `TypeError`. In Angular, expression evaluation is forgiving to `undefined` and `null`.
|
||||
|
||||
* **No Control Flow Statements:** you cannot use the following in an Angular expression:
|
||||
* **No Control Flow Statements:** You cannot use the following in an Angular expression:
|
||||
conditionals, loops, or exceptions.
|
||||
|
||||
* **No Function Declarations:** You cannot declare functions in an Angular expression,
|
||||
even inside `ng-init` directive.
|
||||
|
||||
* **No RegExp Creation With Literal Notation:** You cannot create regular expressions
|
||||
in an Angular expression.
|
||||
|
||||
* **No Comma And Void Operators:** You cannot use `,` or `void` in an Angular expression.
|
||||
|
||||
* **Filters:** You can use {@link guide/filter filters} within expressions to format data before
|
||||
displaying it.
|
||||
@@ -164,11 +172,11 @@ expression. The reason behind this is core to the Angular philosophy that applic
|
||||
be in controllers, not the views. If you need a real conditional, loop, or to throw from a view
|
||||
expression, delegate to a JavaScript method instead.
|
||||
|
||||
## No RegExp creation with literal notation
|
||||
## No function declarations or RegExp creation with literal notation
|
||||
|
||||
You can't create regular expressions from within AngularJS expressions. This is to avoid complex
|
||||
model transformation logic inside templates. Such logic is better placed in a controller or in a dedicated
|
||||
filter where it can be tested properly.
|
||||
You can't declare functions or create regular expressions from within AngularJS expressions. This is
|
||||
to avoid complex model transformation logic inside templates. Such logic is better placed in a
|
||||
controller or in a dedicated filter where it can be tested properly.
|
||||
|
||||
## `$event`
|
||||
|
||||
|
||||
@@ -109,6 +109,7 @@ This is a short list of libraries with specific support and documentation for wo
|
||||
* [ng-book: The Complete Book on AngularJS](http://ng-book.com/) by Ari Lerner
|
||||
* [AngularJS : Novice to Ninja](http://www.amazon.in/AngularJS-Novice-Ninja-Sandeep-Panda/dp/0992279453) by Sandeep Panda
|
||||
* [AngularJS UI Development](http://www.amazon.com/AngularJS-UI-Development-Amit-Ghart-ebook/dp/B00OXVAK7A) by Amit Gharat and Matthias Nehlsen
|
||||
* [Responsive Web Design with AngularJS](http://www.amazon.com/Responsive-Design-AngularJS-Sandeep-Kumar/dp/178439842X) by Sandeep Kumar Patel
|
||||
|
||||
###Videos:
|
||||
* [egghead.io](http://egghead.io/)
|
||||
|
||||
@@ -177,7 +177,7 @@ for example, only a portion of the view needs to be controlled by Angular.
|
||||
|
||||
To examine the scope in the debugger:
|
||||
|
||||
1. right click on the element of interest in your browser and select 'inspect element'. You
|
||||
1. Right click on the element of interest in your browser and select 'inspect element'. You
|
||||
should see the browser debugger with the element you clicked on highlighted.
|
||||
|
||||
2. The debugger allows you to access the currently selected element in the console as `$0`
|
||||
|
||||
@@ -16,8 +16,8 @@ about the phones in the catalog.
|
||||
|
||||
## Data
|
||||
|
||||
Note that the `phones.json` file contains unique ids and image urls for each of the phones. The
|
||||
urls point to the `app/img/phones/` directory.
|
||||
Note that the `phones.json` file contains unique IDs and image URLs for each of the phones. The
|
||||
URLs point to the `app/img/phones/` directory.
|
||||
|
||||
__`app/phones/phones.json`__ (sample snippet):
|
||||
|
||||
@@ -59,7 +59,7 @@ the element attribute.
|
||||
We also added phone images next to each record using an image tag with the {@link
|
||||
ng.directive:ngSrc ngSrc} directive. That directive prevents the
|
||||
browser from treating the Angular `{{ expression }}` markup literally, and initiating a request to
|
||||
invalid url `http://localhost:8000/app/{{phone.imageUrl}}`, which it would have done if we had only
|
||||
invalid URL `http://localhost:8000/app/{{phone.imageUrl}}`, which it would have done if we had only
|
||||
specified an attribute binding in a regular `src` attribute (`<img src="{{phone.imageUrl}}">`).
|
||||
Using the `ngSrc` directive prevents the browser from making an http request to an invalid location.
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ fleshed out the `phone-detail.html` view template.
|
||||
|
||||
## Data
|
||||
|
||||
In addition to `phones.json`, the `app/phones/` directory also contains one json file for each
|
||||
In addition to `phones.json`, the `app/phones/` directory also contains one JSON file for each
|
||||
phone:
|
||||
|
||||
__`app/phones/nexus-s.json`:__ (sample snippet)
|
||||
@@ -53,7 +53,7 @@ show this data in the phone detail view.
|
||||
|
||||
## Controller
|
||||
|
||||
We'll expand the `PhoneDetailCtrl` by using the `$http` service to fetch the json files. This works
|
||||
We'll expand the `PhoneDetailCtrl` by using the `$http` service to fetch the JSON files. This works
|
||||
the same way as the phone list controller.
|
||||
|
||||
__`app/js/controllers.js`:__
|
||||
|
||||
+6
-4
@@ -401,6 +401,8 @@ noop.$inject = [];
|
||||
return (transformationFn || angular.identity)(value);
|
||||
};
|
||||
```
|
||||
* @param {*} value to be returned.
|
||||
* @returns {*} the value passed in.
|
||||
*/
|
||||
function identity($) {return $;}
|
||||
identity.$inject = [];
|
||||
@@ -655,7 +657,7 @@ function arrayRemove(array, value) {
|
||||
* Creates a deep copy of `source`, which should be an object or an array.
|
||||
*
|
||||
* * If no destination is supplied, a copy of the object or array is created.
|
||||
* * If a destination is provided, all of its elements (for array) or properties (for objects)
|
||||
* * If a destination is provided, all of its elements (for arrays) or properties (for objects)
|
||||
* are deleted and then all elements/properties from the source are copied to it.
|
||||
* * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
|
||||
* * If `source` is identical to 'destination' an exception will be thrown.
|
||||
@@ -993,7 +995,7 @@ function toJson(obj, pretty) {
|
||||
* Deserializes a JSON string.
|
||||
*
|
||||
* @param {string} json JSON string to deserialize.
|
||||
* @returns {Object|Array|string|number} Deserialized thingy.
|
||||
* @returns {Object|Array|string|number} Deserialized JSON string.
|
||||
*/
|
||||
function fromJson(json) {
|
||||
return isString(json)
|
||||
@@ -1166,7 +1168,7 @@ function getNgAttribute(element, ngAttr) {
|
||||
* {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other.
|
||||
*
|
||||
* You can specify an **AngularJS module** to be used as the root module for the application. This
|
||||
* module will be loaded into the {@link auto.$injector} when the application is bootstrapped and
|
||||
* module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It
|
||||
* should contain the application code needed or have dependencies on other modules that will
|
||||
* contain the code. See {@link angular.module} for more information.
|
||||
*
|
||||
@@ -1174,7 +1176,7 @@ function getNgAttribute(element, ngAttr) {
|
||||
* document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
|
||||
* would not be resolved to `3`.
|
||||
*
|
||||
* `ngApp` is the easiest, and most common, way to bootstrap an application.
|
||||
* `ngApp` is the easiest, and most common way to bootstrap an application.
|
||||
*
|
||||
<example module="ngAppDemo">
|
||||
<file name="index.html">
|
||||
|
||||
+45
-21
@@ -13,14 +13,15 @@ var ngOptionsMinErr = minErr('ngOptions');
|
||||
*
|
||||
* The `ngOptions` attribute can be used to dynamically generate a list of `<option>`
|
||||
* elements for the `<select>` element using the array or object obtained by evaluating the
|
||||
* `ngOptions` comprehension_expression.
|
||||
* `ngOptions` comprehension expression.
|
||||
*
|
||||
* In many cases, `ngRepeat` can be used on `<option>` elements instead of `ngOptions` to achieve a
|
||||
* similar result. However, the `ngOptions` provides some benefits such as reducing memory and
|
||||
* similar result. However, `ngOptions` provides some benefits such as reducing memory and
|
||||
* increasing speed by not creating a new scope for each repeated instance, as well as providing
|
||||
* more flexibility in how the `select`'s model is assigned via `select as`. `ngOptions` should be
|
||||
* used when the `select` model needs to be bound to a non-string value. This is because an option
|
||||
* element can only be bound to string values at present.
|
||||
* more flexibility in how the `<select>`'s model is assigned via the `select` **`as`** part of the
|
||||
* comprehension expression. `ngOptions` should be used when the `<select>` model needs to be bound
|
||||
* to a non-string value. This is because an option element can only be bound to string values at
|
||||
* present.
|
||||
*
|
||||
* When an item in the `<select>` menu is selected, the array element or object property
|
||||
* represented by the selected option will be bound to the model identified by the `ngModel`
|
||||
@@ -35,28 +36,51 @@ var ngOptionsMinErr = minErr('ngOptions');
|
||||
* array of objects. See an example [in this jsfiddle](http://jsfiddle.net/qWzTb/).
|
||||
* </div>
|
||||
*
|
||||
* ## `select as`
|
||||
* ## `select` **`as`**
|
||||
*
|
||||
* Using `select as` will bind the result of the `select as` expression to the model, but
|
||||
* Using `select` **`as`** will bind the result of the `select` expression to the model, but
|
||||
* the value of the `<select>` and `<option>` html elements will be either the index (for array data sources)
|
||||
* or property name (for object data sources) of the value within the collection. If a `track by` expression
|
||||
* or property name (for object data sources) of the value within the collection. If a **`track by`** expression
|
||||
* is used, the result of that expression will be set as the value of the `option` and `select` elements.
|
||||
*
|
||||
* ### `select as` with `track by`
|
||||
*
|
||||
* Using `select as` together with `track by` is not recommended. Reasoning:
|
||||
* ### `select` **`as`** and **`track by`**
|
||||
*
|
||||
* <div class="alert alert-warning">
|
||||
* Do not use `select` **`as`** and **`track by`** in the same expression. They are not designed to work together.
|
||||
* </div>
|
||||
*
|
||||
* Consider the following example:
|
||||
*
|
||||
* ```html
|
||||
* <select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected">
|
||||
* ```
|
||||
*
|
||||
* ```js
|
||||
* $scope.values = [{
|
||||
* id: 1,
|
||||
* label: 'aLabel',
|
||||
* subItem: { name: 'aSubItem' }
|
||||
* }, {
|
||||
* id: 2,
|
||||
* label: 'bLabel',
|
||||
* subItem: { name: 'bSubItem' }
|
||||
* }];
|
||||
*
|
||||
* $scope.selected = { name: 'aSubItem' };
|
||||
* ```
|
||||
*
|
||||
* With the purpose of preserving the selection, the **`track by`** expression is always applied to the element
|
||||
* of the data source (to `item` in this example). To calculate whether an element is selected, we do the
|
||||
* following:
|
||||
*
|
||||
* 1. Apply **`track by`** to the elements in the array. In the example: `[1, 2]`
|
||||
* 2. Apply **`track by`** to the already selected value in `ngModel`.
|
||||
* In the example: this is not possible as **`track by`** refers to `item.id`, but the selected
|
||||
* value from `ngModel` is `{name: 'aSubItem'}`, so the **`track by`** expression is applied to
|
||||
* a wrong object, the selected element can't be found, `<select>` is always reset to the "not
|
||||
* selected" option.
|
||||
*
|
||||
* - Example: <select ng-options="item.subItem as item.label for item in values track by item.id" ng-model="selected">
|
||||
* values: [{id: 1, label: 'aLabel', subItem: {name: 'aSubItem'}}, {id: 2, label: 'bLabel', subItem: {name: 'bSubItem'}}],
|
||||
* $scope.selected = {name: 'aSubItem'};
|
||||
* - track by is always applied to `value`, with the purpose of preserving the selection,
|
||||
* (to `item` in this case)
|
||||
* - to calculate whether an item is selected we do the following:
|
||||
* 1. apply `track by` to the values in the array, e.g.
|
||||
* In the example: [1,2]
|
||||
* 2. apply `track by` to the already selected value in `ngModel`:
|
||||
* In the example: this is not possible, as `track by` refers to `item.id`, but the selected
|
||||
* value from `ngModel` is `{name: aSubItem}`.
|
||||
*
|
||||
* @param {string} ngModel Assignable angular expression to data-bind to.
|
||||
* @param {string=} name Property name of the form under which the control is published.
|
||||
|
||||
+26
-15
@@ -14,19 +14,26 @@
|
||||
*
|
||||
* Can be one of:
|
||||
*
|
||||
* - `string`: The string is evaluated as an expression and the resulting value is used for substring match against
|
||||
* the contents of the `array`. All strings or objects with string properties in `array` that contain this string
|
||||
* will be returned. The predicate can be negated by prefixing the string with `!`.
|
||||
* - `string`: The string is used for matching against the contents of the `array`. All strings or
|
||||
* objects with string properties in `array` that match this string will be returned. This also
|
||||
* applies to nested object properties.
|
||||
* The predicate can be negated by prefixing the string with `!`.
|
||||
*
|
||||
* - `Object`: A pattern object can be used to filter specific properties on objects contained
|
||||
* by `array`. For example `{name:"M", phone:"1"}` predicate will return an array of items
|
||||
* which have property `name` containing "M" and property `phone` containing "1". A special
|
||||
* property name `$` can be used (as in `{$:"text"}`) to accept a match against any
|
||||
* property of the object. That's equivalent to the simple substring match with a `string`
|
||||
* as described above. The predicate can be negated by prefixing the string with `!`.
|
||||
* For Example `{name: "!M"}` predicate will return an array of items which have property `name`
|
||||
* property of the object or its nested object properties. That's equivalent to the simple
|
||||
* substring match with a `string` as described above. The predicate can be negated by prefixing
|
||||
* the string with `!`.
|
||||
* For example `{name: "!M"}` predicate will return an array of items which have property `name`
|
||||
* not containing "M".
|
||||
*
|
||||
* Note that a named property will match properties on the same level only, while the special
|
||||
* `$` property will match properties on the same level or deeper. E.g. an array item like
|
||||
* `{name: {first: 'John', last: 'Doe'}}` will **not** be matched by `{name: 'John'}`, but
|
||||
* **will** be matched by `{$: 'John'}`.
|
||||
*
|
||||
* - `function(value, index)`: A predicate function can be used to write arbitrary filters. The
|
||||
* function is called for each element of `array`. The final result is an array of those
|
||||
* elements that the predicate returned true for.
|
||||
@@ -39,10 +46,10 @@
|
||||
*
|
||||
* - `function(actual, expected)`:
|
||||
* The function will be given the object value and the predicate value to compare and
|
||||
* should return true if the item should be included in filtered result.
|
||||
* should return true if both values should be considered equal.
|
||||
*
|
||||
* - `true`: A shorthand for `function(actual, expected) { return angular.equals(expected, actual)}`.
|
||||
* this is essentially strict comparison of expected and actual.
|
||||
* - `true`: A shorthand for `function(actual, expected) { return angular.equals(actual, expected)}`.
|
||||
* This is essentially strict comparison of expected and actual.
|
||||
*
|
||||
* - `false|undefined`: A short hand for a function which will look for a substring match in case
|
||||
* insensitive way.
|
||||
@@ -145,6 +152,7 @@ function filterFilter() {
|
||||
|
||||
// Helper functions for `filterFilter`
|
||||
function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
|
||||
var shouldMatchPrimitives = isObject(expression) && ('$' in expression);
|
||||
var predicateFn;
|
||||
|
||||
if (comparator === true) {
|
||||
@@ -163,13 +171,16 @@ function createPredicateFn(expression, comparator, matchAgainstAnyProp) {
|
||||
}
|
||||
|
||||
predicateFn = function(item) {
|
||||
if (shouldMatchPrimitives && !isObject(item)) {
|
||||
return deepCompare(item, expression.$, comparator, false);
|
||||
}
|
||||
return deepCompare(item, expression, comparator, matchAgainstAnyProp);
|
||||
};
|
||||
|
||||
return predicateFn;
|
||||
}
|
||||
|
||||
function deepCompare(actual, expected, comparator, matchAgainstAnyProp) {
|
||||
function deepCompare(actual, expected, comparator, matchAgainstAnyProp, dontMatchWholeObject) {
|
||||
var actualType = typeof actual;
|
||||
var expectedType = typeof expected;
|
||||
|
||||
@@ -188,11 +199,11 @@ function deepCompare(actual, expected, comparator, matchAgainstAnyProp) {
|
||||
var key;
|
||||
if (matchAgainstAnyProp) {
|
||||
for (key in actual) {
|
||||
if ((key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator)) {
|
||||
if ((key.charAt(0) !== '$') && deepCompare(actual[key], expected, comparator, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return dontMatchWholeObject ? false : deepCompare(actual, expected, comparator, false);
|
||||
} else if (expectedType === 'object') {
|
||||
for (key in expected) {
|
||||
var expectedVal = expected[key];
|
||||
@@ -200,9 +211,9 @@ function deepCompare(actual, expected, comparator, matchAgainstAnyProp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var keyIsDollar = key === '$';
|
||||
var actualVal = keyIsDollar ? actual : actual[key];
|
||||
if (!deepCompare(actualVal, expectedVal, comparator, keyIsDollar)) {
|
||||
var matchAnyProperty = key === '$';
|
||||
var actualVal = matchAnyProperty ? actual : actual[key];
|
||||
if (!deepCompare(actualVal, expectedVal, comparator, matchAnyProperty, matchAnyProperty)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,8 +106,7 @@ function limitToFilter() {
|
||||
}
|
||||
}
|
||||
|
||||
var out = [],
|
||||
i, n;
|
||||
var i, n;
|
||||
|
||||
// if abs(limit) exceeds maximum length, trim it
|
||||
if (limit > input.length)
|
||||
@@ -119,14 +118,13 @@ function limitToFilter() {
|
||||
i = 0;
|
||||
n = limit;
|
||||
} else {
|
||||
// zero and NaN check on limit - return empty array
|
||||
if (!limit) return [];
|
||||
|
||||
i = input.length + limit;
|
||||
n = input.length;
|
||||
}
|
||||
|
||||
for (; i < n; i++) {
|
||||
out.push(input[i]);
|
||||
}
|
||||
|
||||
return out;
|
||||
return input.slice(i, n);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -130,9 +130,7 @@ function orderByFilter($parse) {
|
||||
}
|
||||
if (predicate === '') {
|
||||
// Effectively no predicate was passed so we compare identity
|
||||
return reverseComparator(function(a, b) {
|
||||
return compare(a, b);
|
||||
}, descending);
|
||||
return reverseComparator(compare, descending);
|
||||
}
|
||||
get = $parse(predicate);
|
||||
if (get.constant) {
|
||||
@@ -174,14 +172,14 @@ function orderByFilter($parse) {
|
||||
|
||||
function objectToString(value) {
|
||||
if (value === null) return 'null';
|
||||
if (typeof value.toString === 'function') {
|
||||
value = value.toString();
|
||||
if (isPrimitive(value)) return value;
|
||||
}
|
||||
if (typeof value.valueOf === 'function') {
|
||||
value = value.valueOf();
|
||||
if (isPrimitive(value)) return value;
|
||||
}
|
||||
if (typeof value.toString === 'function') {
|
||||
value = value.toString();
|
||||
if (isPrimitive(value)) return value;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ var $compileMinErr = minErr('$compile');
|
||||
* @description
|
||||
* The `$templateRequest` service downloads the provided template using `$http` and, upon success,
|
||||
* stores the contents inside of `$templateCache`. If the HTTP request fails or the response data
|
||||
* of the HTTP request is empty then a `$compile` error will be thrown (the exception can be thwarted
|
||||
* of the HTTP request is empty, a `$compile` error will be thrown (the exception can be thwarted
|
||||
* by setting the 2nd parameter of the function to true).
|
||||
*
|
||||
* @param {string} tpl The HTTP request template URL
|
||||
|
||||
@@ -833,7 +833,8 @@ angular.module('ngAnimate', ['ng'])
|
||||
* promise that was returned when the animation was started.
|
||||
*
|
||||
* ```js
|
||||
* var promise = $animate.addClass(element, 'super-long-animation').then(function() {
|
||||
* var promise = $animate.addClass(element, 'super-long-animation');
|
||||
* promise.then(function() {
|
||||
* //this will still be called even if cancelled
|
||||
* });
|
||||
*
|
||||
|
||||
+19
-12
@@ -297,21 +297,28 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('ngClick',['$aria', function($aria) {
|
||||
.directive('ngClick',['$aria', '$parse', function($aria, $parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, elem, attr) {
|
||||
if ($aria.config('tabindex') && !elem.attr('tabindex')) {
|
||||
elem.attr('tabindex', 0);
|
||||
}
|
||||
compile: function(elem, attr) {
|
||||
var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true);
|
||||
return function(scope, elem, attr) {
|
||||
if ($aria.config('tabindex') && !elem.attr('tabindex')) {
|
||||
elem.attr('tabindex', 0);
|
||||
}
|
||||
|
||||
if ($aria.config('bindKeypress') && !elem.attr('ng-keypress')) {
|
||||
elem.on('keypress', function(event) {
|
||||
if (event.keyCode === 32 || event.keyCode === 13) {
|
||||
scope.$eval(attr.ngClick);
|
||||
}
|
||||
});
|
||||
}
|
||||
if ($aria.config('bindKeypress') && !attr.ngKeypress) {
|
||||
elem.on('keypress', function(event) {
|
||||
if (event.keyCode === 32 || event.keyCode === 13) {
|
||||
scope.$apply(callback);
|
||||
}
|
||||
|
||||
function callback() {
|
||||
fn(scope, { $event: event });
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}])
|
||||
|
||||
Vendored
+14
-14
@@ -1276,7 +1276,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
||||
* and returns true if the url match the current definition.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1290,7 +1290,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
||||
* and returns true if the url match the current definition.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1304,7 +1304,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
||||
* and returns true if the url match the current definition.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1320,7 +1320,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
|
||||
* data string and returns true if the data is as expected.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1336,7 +1336,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* @param {(string|RegExp|function(string))=} data HTTP request body or function that receives
|
||||
* data string and returns true if the data is as expected.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1349,7 +1349,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
*
|
||||
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
||||
* and returns true if the url match the current definition.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1370,7 +1370,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* is in JSON format.
|
||||
* @param {(Object|function(Object))=} headers HTTP headers or function that receives http header
|
||||
* object and returns true if the headers match the current expectation.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*
|
||||
@@ -1405,7 +1405,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
||||
* and returns true if the url match the current definition.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled. See #expect for more info.
|
||||
*/
|
||||
@@ -1419,7 +1419,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
||||
* and returns true if the url match the current definition.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1433,7 +1433,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
||||
* and returns true if the url match the current definition.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1450,7 +1450,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* receives data string and returns true if the data is as expected, or Object if request body
|
||||
* is in JSON format.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1467,7 +1467,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* receives data string and returns true if the data is as expected, or Object if request body
|
||||
* is in JSON format.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1484,7 +1484,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
* receives data string and returns true if the data is as expected, or Object if request body
|
||||
* is in JSON format.
|
||||
* @param {Object=} headers HTTP headers.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
@@ -1497,7 +1497,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
|
||||
*
|
||||
* @param {string|RegExp|function(string)} url HTTP url or function that receives the url
|
||||
* and returns true if the url match the current definition.
|
||||
* @returns {requestHandler} Returns an object with `respond` method that control how a matched
|
||||
* @returns {requestHandler} Returns an object with `respond` method that controls how a matched
|
||||
* request is handled. You can save this object for later use and invoke `respond` again in
|
||||
* order to change how a matched request is handled.
|
||||
*/
|
||||
|
||||
@@ -65,6 +65,33 @@ describe('Filter: filter', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should match primitive array values against top-level `$` property in object expression',
|
||||
function() {
|
||||
var items, expr;
|
||||
|
||||
items = ['something', 'something else', 'another thing'];
|
||||
expr = {$: 'some'};
|
||||
expect(filter(items, expr).length).toBe(2);
|
||||
expect(filter(items, expr)).toEqual([items[0], items[1]]);
|
||||
|
||||
items = [{val: 'something'}, {val: 'something else'}, {val: 'another thing'}];
|
||||
expr = {$: 'some'};
|
||||
expect(filter(items, expr).length).toBe(2);
|
||||
expect(filter(items, expr)).toEqual([items[0], items[1]]);
|
||||
|
||||
items = [123, 456, 789];
|
||||
expr = {$: 1};
|
||||
expect(filter(items, expr).length).toBe(1);
|
||||
expect(filter(items, expr)).toEqual([items[0]]);
|
||||
|
||||
items = [true, false, 'true'];
|
||||
expr = {$: true, ignored: 'false'};
|
||||
expect(filter(items, expr).length).toBe(2);
|
||||
expect(filter(items, expr)).toEqual([items[0], items[2]]);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
it('should take object as predicate', function() {
|
||||
var items = [{first: 'misko', last: 'hevery'},
|
||||
{first: 'adam', last: 'abrons'}];
|
||||
@@ -136,14 +163,30 @@ describe('Filter: filter', function() {
|
||||
});
|
||||
|
||||
|
||||
it('should respect the depth level of a "$" property', function() {
|
||||
var items = [{person: {name: 'Annet', email: 'annet@example.com'}},
|
||||
{person: {name: 'Billy', email: 'me@billy.com'}},
|
||||
{person: {name: 'Joan', email: {home: 'me@joan.com', work: 'joan@example.net'}}}];
|
||||
var expr = {person: {$: 'net'}};
|
||||
it('should match named properties only against named properties on the same level', function() {
|
||||
var expr = {person: {name: 'John'}};
|
||||
var items = [{person: 'John'}, // No match (1 level higher)
|
||||
{person: {name: 'John'}}, // Match (same level)
|
||||
{person: {name: {first: 'John', last: 'Doe'}}}]; // No match (1 level deeper)
|
||||
|
||||
expect(filter(items, expr).length).toBe(1);
|
||||
expect(filter(items, expr)).toEqual([items[0]]);
|
||||
expect(filter(items, expr)).toEqual([items[1]]);
|
||||
});
|
||||
|
||||
|
||||
it('should match any properties on same or deeper level for given "$" property', function() {
|
||||
var items = [{level1: 'test', foo1: 'bar1'},
|
||||
{level1: {level2: 'test', foo2:'bar2'}, foo1: 'bar1'},
|
||||
{level1: {level2: {level3: 'test', foo3: 'bar3'}, foo2: 'bar2'}, foo1: 'bar1'}];
|
||||
|
||||
expect(filter(items, {$: 'ES'}).length).toBe(3);
|
||||
expect(filter(items, {$: 'ES'})).toEqual([items[0], items[1], items[2]]);
|
||||
|
||||
expect(filter(items, {level1: {$: 'ES'}}).length).toBe(2);
|
||||
expect(filter(items, {level1: {$: 'ES'}})).toEqual([items[1], items[2]]);
|
||||
|
||||
expect(filter(items, {level1: {level2: {$: 'ES'}}}).length).toBe(1);
|
||||
expect(filter(items, {level1: {level2: {$: 'ES'}}})).toEqual([items[2]]);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -79,6 +79,16 @@ describe('Filter: orderBy', function() {
|
||||
{ a:new Date('01/01/2014'), b:3 }]);
|
||||
});
|
||||
|
||||
it('should compare timestamps when sorting dates', function() {
|
||||
expect(orderBy([
|
||||
new Date('01/01/2015'),
|
||||
new Date('01/01/2014')
|
||||
])).toEqualData([
|
||||
new Date('01/01/2014'),
|
||||
new Date('01/01/2015')
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
it('should use function', function() {
|
||||
expect(
|
||||
|
||||
@@ -509,6 +509,23 @@ describe('$aria', function() {
|
||||
expect(clickFn).not.toHaveBeenCalled();
|
||||
expect(keypressFn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should update bindings when keypress handled', function() {
|
||||
compileInput('<div ng-click="text = \'clicked!\'">{{text}}</div>');
|
||||
expect(element.text()).toBe('');
|
||||
spyOn(scope.$root, '$digest').andCallThrough();
|
||||
element.triggerHandler({ type: 'keypress', keyCode: 13 });
|
||||
expect(element.text()).toBe('clicked!');
|
||||
expect(scope.$root.$digest).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('should pass $event to ng-click handler as local', function() {
|
||||
compileInput('<div ng-click="event = $event">{{event.type}}' +
|
||||
'{{event.keyCode}}</div>');
|
||||
expect(element.text()).toBe('');
|
||||
element.triggerHandler({ type: 'keypress', keyCode: 13 });
|
||||
expect(element.text()).toBe('keypress13');
|
||||
});
|
||||
});
|
||||
|
||||
describe('actions when bindKeypress set to false', function() {
|
||||
|
||||
Reference in New Issue
Block a user