初识angularjs

1,angular的ng-model带来了双向绑定机制

2,用angular的表达式{{...}}现实在HTML中,存储在我们的$scope

3,在angular中$scope是连接controllers(控制器)和templates(模板view/视图)的主要胶合体。我们可以把我们的model存放在scope上,来达到双向你绑定。

一.html Parser(编译器)

  1. compile(编译):遍历dom找到所有指令,按指令优先级排序,执行conpile函数,把每个compile函数返回的link函数存到一个总的link函数中;
  2. link(链接):将$scope绑定到dom上,在元素上注册事件监听器,$watch监控数据模型;

二. 双向数据绑定

    主要通过脏检测来完成,就是针对旧值保存一份副本出来,如果值发生变化,就回去比较副本和旧值,如果不一样了,就标记为dirty,如果digest次数过多大于10的话,就会抛出异常。所以要尽量减少digest的次数。UI事件,ajax请求或者 timeout 延迟事件,会触发脏检测。

// 核心代码
function Scope() {
    this.$$watchers = [];
}

Scope.prototype.$watch = function(watchFn, listenerFn) {
    var watcher = {
        watchFn: watchFn,
        listenerFn: listenerFn
    };
    this.$$watchers.push(watcher);
}

Scope.prototype.$$digestOnce = function() {
    var self = this;
    var dirty;
    _.forEach(this.$$watchers, function(watch) {
        var newValue = watch.watchFn(self);
        var oldValue = watch.last;
        if (newValue !== oldValue) {
            watch.listenerFn(newValue, oldValue, self);
            dirty = true;
        }
        watch.last = newValue;
    })
    return dirty;
};


Scope.prototype.$digest = function() {
    var dirty;
    do {
        dirty = this.$$digestOnce(); 
    } while (dirty);
};
// 在指令编译时,Angular对input添加了事件监控,会自动将input的值设置到$scope上。
<input ng-model = 'value'>

// 在编译时,Angular使用$watch方法在对应的$scope上添加了监控,一旦$scope中的属性值发生了变化,这里就会跟着变($digest过程)
<p>{{ value }}</p>

三 . 依赖注入

     $injector自动注入:分析匹配参数名 --> fn.$injections = [] --> fn.call或者fn.apply传递需要注入的对象。

angular在每次应用启动时,初始化一个Injector实例,对每一个Angular应用来说,所有的"provider"都是存在相同的providerCache或cache中。

// 拿到依赖项
function getDependency(fn) {
    var args = fn.toString.match(/^[^(]*(s*([^)]*))/m);
    return args[1].split(',');
}

// 查找依赖项对应的对象
function createInjector(cache) {
    this.cache = cache;
}
angular.module = function () {
    modules = {};
    injector = new createInjector(modules);
    return {
        injector: injector,
        factory: function (name, fn) {
            modules[name.trim()] = this.injector.invoke(fn); 
            return this;
        }
    }
};

// 执行时注入

createInjector.prototype = {
    invoke: function (fn, self) {
        argsString = extractArgs(fn);
        args = [];
        argsString.forEach(function (val) {
            args.push(this.cache[val.trim()]);
        }, this);
            return fn.apply(self, args);
    }
}; 
 两种声明依赖的方法
// 数组
angular.module('app').controller('myCtrl', ['$scope', '$location', function ($scope, $location) {
    ...
}])

// $inject
angular.module('app').controller('myCtrl', Ctrl);
function Ctrl($scope) {
    ...
}
Ctrl.$inject = ["$scope", "$location"];

四. 封装指令的基础

  • 指令嵌套
  • 指令处理html元素
  • 指令间的交互

五. 杂

  • service:单例的功能或function,用来完成一些通用的功能,angular内置很多service(以$开头),可以自动注入(构造器注入);
  • angular.module('app') 一切都是从定义模块开始
  • 与dom操作相关的放在directive里,controller将所有东西联合起来
  • 模块就是个容器,将其他东西都放在里面的一个意思
原文地址:https://www.cnblogs.com/colima/p/4673437.html