mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-05-15 18:23:09 +00:00
feat(scope): $evalAsync support
This commit is contained in:
parent
13e7df68a6
commit
3f99cdbdc3
3 changed files with 77 additions and 0 deletions
|
|
@ -1,6 +1,10 @@
|
||||||
<a name="0.9.19"><a/>
|
<a name="0.9.19"><a/>
|
||||||
# 0.9.19 canine-psychokinesis (in-progress) #
|
# 0.9.19 canine-psychokinesis (in-progress) #
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- Scope $evalAsync()
|
||||||
|
|
||||||
|
|
||||||
# Breaking Changes
|
# Breaking Changes
|
||||||
- Controller constructor functions are now looked up on scope first and then on window.
|
- Controller constructor functions are now looked up on scope first and then on window.
|
||||||
- angular.equals now use === which means that things which used to be equal are no longer.
|
- angular.equals now use === which means that things which used to be equal are no longer.
|
||||||
|
|
|
||||||
38
src/Scope.js
38
src/Scope.js
|
|
@ -96,6 +96,7 @@ function Scope() {
|
||||||
this.$$phase = this.$parent = this.$$watchers =
|
this.$$phase = this.$parent = this.$$watchers =
|
||||||
this.$$nextSibling = this.$$childHead = this.$$childTail = null;
|
this.$$nextSibling = this.$$childHead = this.$$childTail = null;
|
||||||
this['this'] = this.$root = this;
|
this['this'] = this.$root = this;
|
||||||
|
this.$$asyncQueue = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -168,6 +169,7 @@ Scope.prototype = {
|
||||||
child['this'] = child;
|
child['this'] = child;
|
||||||
child.$parent = this;
|
child.$parent = this;
|
||||||
child.$id = nextUid();
|
child.$id = nextUid();
|
||||||
|
child.$$asyncQueue = [];
|
||||||
child.$$phase = child.$$watchers =
|
child.$$phase = child.$$watchers =
|
||||||
child.$$nextSibling = child.$$childHead = child.$$childTail = null;
|
child.$$nextSibling = child.$$childHead = child.$$childTail = null;
|
||||||
if (this.$$childHead) {
|
if (this.$$childHead) {
|
||||||
|
|
@ -319,6 +321,7 @@ Scope.prototype = {
|
||||||
var child,
|
var child,
|
||||||
watch, value, last,
|
watch, value, last,
|
||||||
watchers = this.$$watchers,
|
watchers = this.$$watchers,
|
||||||
|
asyncQueue = this.$$asyncQueue,
|
||||||
length, count = 0,
|
length, count = 0,
|
||||||
dirtyCount, ttl = 100,
|
dirtyCount, ttl = 100,
|
||||||
recheck = !this.$parent || !this.$parent.$$phase;
|
recheck = !this.$parent || !this.$parent.$$phase;
|
||||||
|
|
@ -328,6 +331,13 @@ Scope.prototype = {
|
||||||
}
|
}
|
||||||
this.$$phase = '$digest';
|
this.$$phase = '$digest';
|
||||||
do {
|
do {
|
||||||
|
while(asyncQueue.length) {
|
||||||
|
try {
|
||||||
|
this.$eval(asyncQueue.shift());
|
||||||
|
} catch (e) {
|
||||||
|
this.$service('$exceptionHandler')(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
dirtyCount = 0;
|
dirtyCount = 0;
|
||||||
if (watchers) {
|
if (watchers) {
|
||||||
// process our watches
|
// process our watches
|
||||||
|
|
@ -438,6 +448,34 @@ Scope.prototype = {
|
||||||
return fn(this);
|
return fn(this);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @workInProgress
|
||||||
|
* @ngdoc function
|
||||||
|
* @name angular.scope.$evalAsync
|
||||||
|
* @function
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Executes the expression on the current scope at a later point in time.
|
||||||
|
*
|
||||||
|
* The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only that:
|
||||||
|
*
|
||||||
|
* - it will execute in the current script execution context (before any DOM rendering).
|
||||||
|
* - at least one {@link angular.scope.$digest $digest cycle} will be performed after
|
||||||
|
* `expression` execution.
|
||||||
|
*
|
||||||
|
* Any exceptions from the execution of the expression are forwarded to the
|
||||||
|
* {@link angular.service.$exceptionHandler $exceptionHandler} service.
|
||||||
|
*
|
||||||
|
* @param {(string|function())=} expression An angular expression to be executed.
|
||||||
|
*
|
||||||
|
* - `string`: execute using the rules as defined in {@link guide/dev_guide.expressions expression}.
|
||||||
|
* - `function(scope)`: execute the function with the current `scope` parameter.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
$evalAsync: function(expr) {
|
||||||
|
this.$$asyncQueue.push(expr);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @workInProgress
|
* @workInProgress
|
||||||
* @ngdoc function
|
* @ngdoc function
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,41 @@ describe('Scope', function(){
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('$evalAsync', function(){
|
||||||
|
|
||||||
|
it('should run callback before $watch', function(){
|
||||||
|
var log = '';
|
||||||
|
var child = root.$new();
|
||||||
|
root.$evalAsync(function(scope){ log += 'parent.async;'; });
|
||||||
|
root.$watch('value', function(){ log += 'parent.$digest;'; });
|
||||||
|
child.$evalAsync(function(scope){ log += 'child.async;'; });
|
||||||
|
child.$watch('value', function(){ log += 'child.$digest;'; });
|
||||||
|
root.$digest();
|
||||||
|
expect(log).toEqual('parent.async;parent.$digest;child.async;child.$digest;');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should cause a $digest rerun', function(){
|
||||||
|
root.log = '';
|
||||||
|
root.value = 0;
|
||||||
|
root.$watch('value', 'log = log + ".";');
|
||||||
|
root.$watch('init', function(){
|
||||||
|
root.$evalAsync('value = 123; log = log + "=" ');
|
||||||
|
expect(root.value).toEqual(0);
|
||||||
|
});
|
||||||
|
root.$digest();
|
||||||
|
expect(root.log).toEqual('.=.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should run async in the same order as added', function(){
|
||||||
|
root.log = '';
|
||||||
|
root.$evalAsync("log = log + 1");
|
||||||
|
root.$evalAsync("log = log + 2");
|
||||||
|
root.$digest();
|
||||||
|
expect(root.log).toBe('12');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('$apply', function(){
|
describe('$apply', function(){
|
||||||
it('should apply expression with full lifecycle', function(){
|
it('should apply expression with full lifecycle', function(){
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue