function Scope() {
this.$$watchers = []; // 监听器数组
this.$$lastDirtyWatch = null; // 每次digest循环的最后一个脏的watcher, 用于优化digest循环
this.$$asyncQueue = []; // scope上的异步队列
this.$$applyAsyncQueue = []; // scope上的异步apply队列
this.$$applyAsyncId = null; //异步apply信息
this.$$postDigestQueue = []; // postDigest执行队列
this.$$phase = null; // 储存scope上正在做什么,值有:digest/apply/null
this.$root = this; // rootScope
this.$$listeners = {}; // 存储包含自定义事件键值对的对象
this.$$children = []; // 存储当前scope的儿子Scope,以便$digest循环递归
}
/* $watch方法:向watchers数组中添加watcher对象,以便对应调用 */
Scope.prototype.$watch = function(watchFn, listenerFn, valueEq) {
var self = this;
watchFn = $parse(watchFn);
// watchDelegate: 针对watch expression是常量和 one-time-binding的情况,进行优化。在第一次初始化之后删除watch
if(watchFn.$$watchDelegate) {
return watchFn.$$watchDelegate(self, listenerFn, valueEq, watchFn);
}
var watcher = {
watchFn: watchFn,
listenerFn: listenerFn || function() {},
valueEq: !!valueEq,
last: initWatchVal
};
this.$$watchers.unshift(watcher);
this.$root.$$lastDirtyWatch = null;
return function() {
var index = self.$$watchers.indexOf(watcher);
if(index >= 0) {
self.$$watchers.splice(index, 1);
self.$root.$$lastDirtyWatch = null;
}
};
};
Scope.prototype.$$digestOnce = function() {
var dirty;
var continueLoop = true;
var self = this;
this.$$everyScope(function(scope) {
var newValue, oldValue;
_.forEachRight(scope.$$watchers, function(watcher) {
try {
if(watcher) {
newValue = watcher.watchFn(scope);
oldValue = watcher.last;
if(!scope.$$areEqual(newValue, oldValue, watcher.valueEq)) {
scope.$root.$$lastDirtyWatch = watcher;
watcher.last = (watcher.valueEq ? _.cloneDeep(newValue) : newValue);
watcher.listenerFn(newValue,
(oldValue === initWatchVal? newValue : oldValue), scope);
dirty = true;
} else if(scope.$root.$$lastDirtyWatch === watcher) {
continueLoop = false;
return false;
}
}
} catch(e) {
console.error(e);
}
});
return continueLoop;
});
return dirty;
};
// digest循环的外循环,保持循环直到没有脏值为止
Scope.prototype.$digest = function() {
var ttl = TTL;
var dirty;
this.$root.$$lastDirtyWatch = null;
this.$beginPhase('$digest');
if(this.$root.$$applyAsyncId) {
clearTimeout(this.$root.$$applyAsyncId);
this.$$flushApplyAsync();
}
do {
while (this.$$asyncQueue.length) {
try {
var asyncTask = this.$$asyncQueue.shift();
asyncTask.scope.$eval(asyncTask.expression);
} catch(e) {
console.error(e);
}
}
dirty = this.$$digestOnce();
if((dirty || this.$$asyncQueue.length) && !(ttl--)) {
this.$clearPhase();
throw TTL + ' digest iterations reached';
}
} while (dirty || this.$$asyncQueue.length);
this.$clearPhase();
while(this.$$postDigestQueue.length) {
try {
this.$$postDigestQueue.shift()();
} catch(e) {
console.error(e);
}
}
};
Scope.prototype.$eval = function(expr, locals) {
return $parse(expr)(this, locals);
};
Scope.prototype.$apply = function(expr) {
try {
this.$beginPhase('$apply');
return this.$eval(expr);
} finally {
this.$clearPhase();
this.$root.$digest();
}
};
Scope.prototype.$evalAsync = function(expr) {
var self = this;
if(!self.$$phase && !self.$$asyncQueue.length) {
setTimeout(function() {
if(self.$$asyncQueue.length) {
self.$root.$digest();
}
}, 0);
}
this.$$asyncQueue.push({
scope: this,
expression: expr
});
};
while (this.$$asyncQueue.length) {
try {
var asyncTask = this.$$asyncQueue.shift();
asyncTask.scope.$eval(asyncTask.expression);
} catch(e) {
console.error(e);
}
}
/* 这个方法用于 知道需要在短时间内多次使用$apply的情况,
能够对短时间内多次$digest循环进行合并,
是针对$digest循环的优化策略
*/
Scope.prototype.$applyAsync = function(expr) {
var self = this;
self.$$applyAsyncQueue.push(function() {
self.$eval(expr);
});
if(self.$root.$$applyAsyncId === null) {
self.$root.$$applyAsyncId = setTimeout(function() {
self.$apply(_.bind(self.$$flushApplyAsync, self));
}, 0);
}
};
/* $$postDigest 用于在下一次digest循环后执行函数队列
不同于applyAsync 和 evalAsync, 它不触发digest循环
*/
Scope.prototype.$$postDigest = function(fn) {
this.$$postDigestQueue.push(fn);
};
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有