angularjs面试(一)
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
比如,如果你使用了JavaScript中的setTimeout()来更新一个scope model,那么AngularJS就没有办法知道你更改了什么。这种情况下,调 用$apply()就是你的责任了,通过调用它来触发一轮$digest循环。类似地,如果你有一个指令用来设置一个DOM事件listener并且在 该listener中修改了一些models,那么你也需要通过手动调用$apply()来确保变更会被正确的反映到view中。
}; });
});
在上面的例子中我们为一个服务定义了一个叫做greeting的新provider;我么可以把一个叫做greeting的变量注入到任何可注入的函数中(例 如控制器,在后面会讲到)然后Angular就会调用这个provider的$get函数来返回这个服务的一个实例。在上面的例子中,被注入的是一个函 数,它接受一个叫做name的参数并且根据这个参数alert一条信息。
Note: $digest循环最少也会运行两次,即使在listener函数中并没有改变任何model。正如上面讨论的那样,它会多运行一次来确保models没 有变化。
AngularJS中的$watch方法,这个方法很接近事件的注册和监听:
$scope.$watch( function(scope) { return scope.someValue; }, function(newValue, oldValue, scope) { // listener code defined here }
5.1 angular是怎么处理指令的
浏览器渲染一个页面时,本质上是读html标志,然后建立dom节点,当dom树创建完毕后,广播事件给我们。当使用script标签加载angular 应用程序代码时,angular会监听上面的dom完成事件,查找带有ng-app的元素,然后以这个元素为起点,递归查找所有子元素里面符合应 用程序定义好的指令规则。
您使用的浏览器不受支持建议使用新版浏览器
angularjs面 试 ( 一 )
1、 angular的 数 据 绑 定 采 用 什 么 机 制 ? 详 述 原 理
angular进行双向数据绑定主要是他的脏检查机制。只负责对发生于AngularJS上下文环境中的变更会做出自动地响应, 在里面触发进入 angular的digest流程,进入$digest cycle:
$digest循环不会只运行一次。在当前的一次循环结束后,它会再执行一次循环用来检查是否有models发生了变化。这就是脏检查(Dirty Checking),它用来处理在listener函数被执行时可能引起的model变化。因此,$digest循环会持续运行直到model不再发生变化,或 者$digest循环的次数达到了10次。因此,尽可能地不要在listener函数中修改model。
4、 有 几 种 依 赖 注 入 的 方 式
1)简单注入方式
myModule.controller('myCtrl', myCtrl);
AngularJs会扫描function的参数,提取参数的名称(name)作为function的依赖,
所以这种方式要求保证参数名称的正确性,但对参数的顺序并e以及value全部都是用来定义一个providr的简写,它们提供了一种方式来定义一个provider而无需输入所有的复杂的代码。
注入器($injector)
注入器负责从我们通过$provide创建的服务中创建注入的实例。每一个AngularJS应用都有唯一一个$injector,当应用启动的时候它被创造 出来,你可以通过将$injector注入到任何可注入函数中来得到它($injector知道如何注入它自己!)。一旦你拥有了$injector,你可以动过 调用get函数来获得任何一个已经被定义过的服务的实例。
控制器定义函数 指令定义函数 过滤器定义函数 provider中的$get方法(也就是factory函数)
由于constant和value总是返回一个静态值,它们不会通过注入器被调用,因此你不能在其中注入任何东西。
在config阶段,只有provider能被注入(只有两个例外是$provide和$injector)。有一个例外:constant,由于它们不能被改变,因此它不能被 注入到config中(这就是它和value之间的不同之处)。它们只能通过名字被获取。
每一个依赖的参数值(字符串)都会以相同的顺序存放在一个数组里,数组的值与后面的function参数一一对应,这样即使压缩了也不会有 什么问题。
3)显示调用function的$inject
function myCtrl(a, b) { //$scope, Project,故意改成a,b模拟压缩后的情形
} myCtrl.$inject = ['$scope', 'Project']; myModule.controller('PhoneDetailCtrl', myCtrl);
通过设置funciton的$inject属性,可以达到依赖注入的效果;
5、 directive中 compile和 link的 区 别
}; $injector.invoke(myFunction);
如果注入器只是创建一个服务的实例一次的话,那么它也没什么了不起的。它的厉害之处在于,他能够通过服务名称缓存从一个provider中 返回的任何东西,当你下一次再使用这个服务时,你将会得到同一个对象。
因此,你可以通过调用$injector.invike将服务注入到任何函数中也是合情合理的了。包括:
);
$watch方法的第一个参数是一个函数,它通常被称为watch函数,它的返回值声明需要监听的变量;第二个参数是listener,也就是回调函 数,在变量发生改变的时候会被调用。
$digest函数中,会逐个检查$watch方法中注册的watch函数,如果该函数返回的值和上一次检查中返回的值不一样的话,就会触发对应的 listener函数。拿{{ }}表达式作为例子,该表达式编译得到的listener的行为就是将后台的最新变量给同步到前端。这么一来,就完成了一个简 单的数据绑定。
app.config(function($provide) { $provide.provider('greeting', function() {
this.$get = function() { return function(name) {
alert("Hello, " + name); };
3、 依 赖 注 入
让我们可以不用自己实例化就能创建依赖对象的方法. 简单的来说, 依赖是以注入的方式传递的. 在Web应用中, Angular让我们可以通过DI 来创建像Controllers和Directives这样的对象. 我们还可以创建自己的依赖对象, 当我们要实例化它们时, Angular能自动实现注入.
$apply方法。这个方法能够触发$digest方法。$digest方法的执行就标志着一轮Digest Cycle的开始。
Note: $scope.$apply()会自动地调用$rootScope.$digest()。$apply()方法有两种形式。第一种会接受一个function作为参数,执行 该function并且触发一轮$digest循环。第二种会不接受任何参数,只是触发一轮$digest循环。
DOM事件,譬如用户输入文本,点击按钮等。(ng-click) XHR响应事件 ($http) 浏览器Location变更事件 ($location) Timer事件($timeout, $interval) 执行$digest()或$apply()
1)当你往UI界面上绑定数据时,angular就会把它加入到$watch队列 2)当你绑定的事件触发时,就会触发$apply,apply会调用$rootScope.$digest(),进入angular context,触发digest循环 3)当$digest循环开始后,它会检查watcher队列中的每个watcher。这些watchers会检查当前的值和之前的值是否一样,有没有发生改变, 如果发生了改变,则调用回调函数,将新的值更新到界面上。 假设你将ng-click指令关联到了一个button上,并传入了一个function名到ng-click上。当该button被点击时,AngularJS会将此function包装到 一个wrapping function中,然后传入到$scope.$apply()。因此,你的function会正常被执行,修改models(如果需要的话),此时一 轮$digest循环也会被触发,用来确保view也会被更新。
控制器函数是可以被注入的,但是控制器本身是不能被注入到任何东西里面去的。这是因为控制器不是通过provider创建的。
filter和directive和controller的运行方式相同;filter会使用一个叫做$filter的服务以及它的provider $filterProvider,而directive使用一个叫做 $compile的服务以及它的provider $compileProvidr。
angularjs只负责对发生于AngularJS上下文环境中的变更会做出自动地响应(即,在$apply()方法中发生的对于models的更 改)。AngularJS的built-in指令就是这样做的,所以任何的model变更都会被反映到view中。但是,如果你在AngularJS上下文之外的任何地 方修改了model,那么你就需要通过手动调用$apply()来通知AngularJS。这就像告诉AngularJS,你修改了一些models,希望AngularJS帮 你触发watchers来做出正确的响应。
provider服务
$provide服务负责告诉Angular如何创造一个新的可注入的东西:即服务(service)。服务会被叫做provider的东西来定义,你可以使用 $provide来创建一个provider。你需要使用$provide中的provider方法来定义一个provider,同时你也可以通过要求改服务被注入到一个应用 的config函数中来获得$provide服务。
需要记住的是你总是应该使用接受一个function作为参数的$apply()方法。这是因为当你传入一个function到$apply()中的时候,这 个function会被包装到一个try…catch块中,所以一旦有异常发生,该异常会被$exceptionHandler service处理。
2、 $apply()和 $digest()的 区 别
但是这种注入方式有一个问题,当我们将项目发布到正式环境时都会压缩我们的代码,这时function的参数可能会变成a,b,这就会导致我们 的代码出现问题,下面两种注入方式可以帮我们解决这个问题。
2)数组注释法
myModule.controller('myCtrl', ['$scope', 'Preject', function($scope, Project)
安全性:$apply()可以接收一个参数作为function(),这个 function 会被包装到一个 try … catch 块中,所以一旦有异常发生,该异常会被 $exceptionHandler service 处理。
$apply会使ng进入 $digest cycle , 并从$rootScope开始遍历(深度优先)检查数据变更。 $digest仅会检查该scope和它的子scope,当你确定当前操作仅影响它们时,用$digest可以稍微提升性能。
var greeting = $injector.get('greeting'); greeting('Ford Prefect');
注入器同样也负责将服务注入到函数中;例如,你可以魔法般的将服务注入到任何函数中,只要你使用了注入器的invoke方法:
var myFunction = function(greeting) { greeting('Ford Prefect');
}; });
});
在上面的例子中我们为一个服务定义了一个叫做greeting的新provider;我么可以把一个叫做greeting的变量注入到任何可注入的函数中(例 如控制器,在后面会讲到)然后Angular就会调用这个provider的$get函数来返回这个服务的一个实例。在上面的例子中,被注入的是一个函 数,它接受一个叫做name的参数并且根据这个参数alert一条信息。
Note: $digest循环最少也会运行两次,即使在listener函数中并没有改变任何model。正如上面讨论的那样,它会多运行一次来确保models没 有变化。
AngularJS中的$watch方法,这个方法很接近事件的注册和监听:
$scope.$watch( function(scope) { return scope.someValue; }, function(newValue, oldValue, scope) { // listener code defined here }
5.1 angular是怎么处理指令的
浏览器渲染一个页面时,本质上是读html标志,然后建立dom节点,当dom树创建完毕后,广播事件给我们。当使用script标签加载angular 应用程序代码时,angular会监听上面的dom完成事件,查找带有ng-app的元素,然后以这个元素为起点,递归查找所有子元素里面符合应 用程序定义好的指令规则。
您使用的浏览器不受支持建议使用新版浏览器
angularjs面 试 ( 一 )
1、 angular的 数 据 绑 定 采 用 什 么 机 制 ? 详 述 原 理
angular进行双向数据绑定主要是他的脏检查机制。只负责对发生于AngularJS上下文环境中的变更会做出自动地响应, 在里面触发进入 angular的digest流程,进入$digest cycle:
$digest循环不会只运行一次。在当前的一次循环结束后,它会再执行一次循环用来检查是否有models发生了变化。这就是脏检查(Dirty Checking),它用来处理在listener函数被执行时可能引起的model变化。因此,$digest循环会持续运行直到model不再发生变化,或 者$digest循环的次数达到了10次。因此,尽可能地不要在listener函数中修改model。
4、 有 几 种 依 赖 注 入 的 方 式
1)简单注入方式
myModule.controller('myCtrl', myCtrl);
AngularJs会扫描function的参数,提取参数的名称(name)作为function的依赖,
所以这种方式要求保证参数名称的正确性,但对参数的顺序并e以及value全部都是用来定义一个providr的简写,它们提供了一种方式来定义一个provider而无需输入所有的复杂的代码。
注入器($injector)
注入器负责从我们通过$provide创建的服务中创建注入的实例。每一个AngularJS应用都有唯一一个$injector,当应用启动的时候它被创造 出来,你可以通过将$injector注入到任何可注入函数中来得到它($injector知道如何注入它自己!)。一旦你拥有了$injector,你可以动过 调用get函数来获得任何一个已经被定义过的服务的实例。
控制器定义函数 指令定义函数 过滤器定义函数 provider中的$get方法(也就是factory函数)
由于constant和value总是返回一个静态值,它们不会通过注入器被调用,因此你不能在其中注入任何东西。
在config阶段,只有provider能被注入(只有两个例外是$provide和$injector)。有一个例外:constant,由于它们不能被改变,因此它不能被 注入到config中(这就是它和value之间的不同之处)。它们只能通过名字被获取。
每一个依赖的参数值(字符串)都会以相同的顺序存放在一个数组里,数组的值与后面的function参数一一对应,这样即使压缩了也不会有 什么问题。
3)显示调用function的$inject
function myCtrl(a, b) { //$scope, Project,故意改成a,b模拟压缩后的情形
} myCtrl.$inject = ['$scope', 'Project']; myModule.controller('PhoneDetailCtrl', myCtrl);
通过设置funciton的$inject属性,可以达到依赖注入的效果;
5、 directive中 compile和 link的 区 别
}; $injector.invoke(myFunction);
如果注入器只是创建一个服务的实例一次的话,那么它也没什么了不起的。它的厉害之处在于,他能够通过服务名称缓存从一个provider中 返回的任何东西,当你下一次再使用这个服务时,你将会得到同一个对象。
因此,你可以通过调用$injector.invike将服务注入到任何函数中也是合情合理的了。包括:
);
$watch方法的第一个参数是一个函数,它通常被称为watch函数,它的返回值声明需要监听的变量;第二个参数是listener,也就是回调函 数,在变量发生改变的时候会被调用。
$digest函数中,会逐个检查$watch方法中注册的watch函数,如果该函数返回的值和上一次检查中返回的值不一样的话,就会触发对应的 listener函数。拿{{ }}表达式作为例子,该表达式编译得到的listener的行为就是将后台的最新变量给同步到前端。这么一来,就完成了一个简 单的数据绑定。
app.config(function($provide) { $provide.provider('greeting', function() {
this.$get = function() { return function(name) {
alert("Hello, " + name); };
3、 依 赖 注 入
让我们可以不用自己实例化就能创建依赖对象的方法. 简单的来说, 依赖是以注入的方式传递的. 在Web应用中, Angular让我们可以通过DI 来创建像Controllers和Directives这样的对象. 我们还可以创建自己的依赖对象, 当我们要实例化它们时, Angular能自动实现注入.
$apply方法。这个方法能够触发$digest方法。$digest方法的执行就标志着一轮Digest Cycle的开始。
Note: $scope.$apply()会自动地调用$rootScope.$digest()。$apply()方法有两种形式。第一种会接受一个function作为参数,执行 该function并且触发一轮$digest循环。第二种会不接受任何参数,只是触发一轮$digest循环。
DOM事件,譬如用户输入文本,点击按钮等。(ng-click) XHR响应事件 ($http) 浏览器Location变更事件 ($location) Timer事件($timeout, $interval) 执行$digest()或$apply()
1)当你往UI界面上绑定数据时,angular就会把它加入到$watch队列 2)当你绑定的事件触发时,就会触发$apply,apply会调用$rootScope.$digest(),进入angular context,触发digest循环 3)当$digest循环开始后,它会检查watcher队列中的每个watcher。这些watchers会检查当前的值和之前的值是否一样,有没有发生改变, 如果发生了改变,则调用回调函数,将新的值更新到界面上。 假设你将ng-click指令关联到了一个button上,并传入了一个function名到ng-click上。当该button被点击时,AngularJS会将此function包装到 一个wrapping function中,然后传入到$scope.$apply()。因此,你的function会正常被执行,修改models(如果需要的话),此时一 轮$digest循环也会被触发,用来确保view也会被更新。
控制器函数是可以被注入的,但是控制器本身是不能被注入到任何东西里面去的。这是因为控制器不是通过provider创建的。
filter和directive和controller的运行方式相同;filter会使用一个叫做$filter的服务以及它的provider $filterProvider,而directive使用一个叫做 $compile的服务以及它的provider $compileProvidr。
angularjs只负责对发生于AngularJS上下文环境中的变更会做出自动地响应(即,在$apply()方法中发生的对于models的更 改)。AngularJS的built-in指令就是这样做的,所以任何的model变更都会被反映到view中。但是,如果你在AngularJS上下文之外的任何地 方修改了model,那么你就需要通过手动调用$apply()来通知AngularJS。这就像告诉AngularJS,你修改了一些models,希望AngularJS帮 你触发watchers来做出正确的响应。
provider服务
$provide服务负责告诉Angular如何创造一个新的可注入的东西:即服务(service)。服务会被叫做provider的东西来定义,你可以使用 $provide来创建一个provider。你需要使用$provide中的provider方法来定义一个provider,同时你也可以通过要求改服务被注入到一个应用 的config函数中来获得$provide服务。
需要记住的是你总是应该使用接受一个function作为参数的$apply()方法。这是因为当你传入一个function到$apply()中的时候,这 个function会被包装到一个try…catch块中,所以一旦有异常发生,该异常会被$exceptionHandler service处理。
2、 $apply()和 $digest()的 区 别
但是这种注入方式有一个问题,当我们将项目发布到正式环境时都会压缩我们的代码,这时function的参数可能会变成a,b,这就会导致我们 的代码出现问题,下面两种注入方式可以帮我们解决这个问题。
2)数组注释法
myModule.controller('myCtrl', ['$scope', 'Preject', function($scope, Project)
安全性:$apply()可以接收一个参数作为function(),这个 function 会被包装到一个 try … catch 块中,所以一旦有异常发生,该异常会被 $exceptionHandler service 处理。
$apply会使ng进入 $digest cycle , 并从$rootScope开始遍历(深度优先)检查数据变更。 $digest仅会检查该scope和它的子scope,当你确定当前操作仅影响它们时,用$digest可以稍微提升性能。
var greeting = $injector.get('greeting'); greeting('Ford Prefect');
注入器同样也负责将服务注入到函数中;例如,你可以魔法般的将服务注入到任何函数中,只要你使用了注入器的invoke方法:
var myFunction = function(greeting) { greeting('Ford Prefect');