本人和 angularjs 渊源很深,在 2015 年参加实习时,公司要求使用 angularjs,那时候是 angularjs 最火的时候,那时我就做了入门学习,在正式参加工作后,使用 ionic 开发混合 app,那时候对于对以移动端很感兴趣,就一头扎进 angularjs,对 angularjs 提供的能力,感觉很神奇,于是决定解开他的神秘面纱!
概括
旨在理解 angularjs 中的核心概念
- 指令系统
- 模块注册
- 依赖注入
- 双向绑定
- 作用域分离
- 脏检测机制
我们主要学习 DOMCompiler、Scope、Provider 对象。
Provider
主要任务有:
- 提供注册 directive、controller、service 的方法
- 提供 get 方法得到特定模块
- 通过 _providers 对象保存注册的模块
- 通过 _cache 对象保存模块的结果
DOMCompiler
看到这个对象,是让我最醒悟的地方,之前一直不解,为什么能识别我的指令,并且发挥他的作用。
- bootstrap 方法:很简单,启动项目,调用 compile 函数扫描整个 dom
- compile 方法
- 扫描整个 dom 结构,如果节点的属性可以在 _privider 的指令部分找到,则说明这是我们定义的指令
- 根据配置,判断是否需要创建子作用于,执行 link 函数
Scope
属性
- $$watchers:监听数组
- $$children:子元素
- $parent:父元素
- $id:唯一标识
函数
- $new:新建 Scope,并继承当前 scope
- $destroy:销毁当前 Scope
- $watch:新增 $$watchers 数组元素,元素属性有
- exp:被监测表达试
- fn:发生改变待执行的函数
- last:保存上一次的值,用于比较
- $digest:脏检测核心
- 默认 dirty 为 false,遍历 $$watchers 数组,比较 current 和 last 值,如果不同,设置 dirty 为 true,同时修改 last 值和执行函数 fn
- 调用子作用域名 $$children 的 $digest 函数
- $eval:执行,支持数组和字符串
常用指令
直接用代码说话吧
Provider.directive('ngl-bind', function () {
return {
scope: false,
link: function (el, scope, exp) {
el.innerHTML = scope.$eval(exp);
scope.$watch(exp, function (val) {
el.innerHTML = val;
});
}
}
})
Provider.directive('ngl-model', function () {
return {
link: function (el, scope, exp) {
el.onkeyup = function () {
scope[exp] = el.value;
scope.$digest();
};
scope.$watch(exp, function (val) {
el.value = val;
});
}
};
});
Provider.directive('ngl-controller', function () {
return {
scope: true,// 每个controller生成一个新的scope对象
link: function (el, scope, exp) {
var ctrl = Provider.get(exp + Provider.CONTROLLERS_SUFFIX);
Provider.invoke(ctrl, { $scope: scope });
}
};
});
Provider.directive('ngl-click', function () {
return {
scope: false,
link: function (el, scope, exp) {
el.onclick = function () {
scope.$eval(exp);
scope.$digest();
};
}
};
});