码迷,mamicode.com
首页 > 其他好文 > 详细

如何权衡自己的angular水准

时间:2016-10-31 21:48:06      阅读:366      评论:0      收藏:0      [点我收藏+]

标签:模块开发   函数   app   优化   强制   direct   filter   自定义   树状   

angular是现在常用的一个前端MVVM框架,感受下下面的问题权衡下自己的水准吧。

1. angular的数据绑定采用什么机制?详述原理
2. 两个平级界面块a和b,如果a中触发一个事件,有哪些方式能让b知道,详述原理
3. 一个angular应用应当如何良好地分层?
4. angular应用常用哪些路由库,各自的区别是什么?
5. 如果通过angular的directive规划一套全组件化体系,可能遇到哪些挑战?
6. 分属不同团队进行开发的angular应用,如果要做整合,可能会遇到哪些问题,如何解决?
7. angular的缺点有哪些?
8. 如何看待angular 1.2中引入的controller as 语法?
9. 详述angular的“依赖注入”
10. 如何看待angular 2……

上面是需要长篇大论的问题,再来一些小问题:

1. ng-if跟ng-show/hide的区别有哪些?
2. ng-repeat迭代数组的时候,如果数组中有相同值,会有什么问题,如何解决?
3. ng-click中写的表达式,能使用JS原生对象上的方法,比如Math.max之类的吗?为什么?
4. {{now | ‘yyyy-MM-dd‘}}这种表达式里面,竖线和后面的参数通过什么方式可以自定义?
5. factory和service,provider是什么关系?
 
 
 
答案附在下面,存在主观因素,如存疑,可再自行搜索答案
 
从小问题开始:

1. ng-if跟ng-show/hide的区别有哪些?

第一点区别是,ng-if 在后面表达式为 true 的时候才创建这个 dom 节点,ng-show 是初始时就创建了,用 display:block 和 display:none 来控制显示和不显示。


第二点区别是,ng-if 会(隐式地)产生新作用域,ng-switch 、 ng-include 等会动态创建一块界面的也是如此。


2. ng-repeat迭代数组的时候,如果数组中有相同值,会有什么问题,如何解决?


会提示 Duplicates in a repeater are not allowed. 加 track by $index 可解决。当然,也可以 trace by 任何一个普通的值,只要能唯一性标识数组中的每一项即可(建立 dom 和数据之间的关联)。


3. ng-click中写的表达式,能使用JS原生对象上的方法,比如Math.max之类的吗?为什么?


不可以。只要是在页面中,就不能直接调用原生的 JS 方法,因为这些并不存在于与页面对应的 Controller 的 $scope 中。除非在 $scope 中添加了这个函数:

$scope.parseInt = function(x){
    return parseInt(x);
}

4. {{now | ‘yyyy-MM-dd‘}}这种表达式里面,竖线和后面的参数通过什么方式可以自定义?


定义方式:

app.filter(‘过滤器名称‘,function(){
    return function(需要过滤的对象, 过滤器参数1, 过滤器参数2, ...){
        //...做一些事情   
        return 处理后的对象;
    }
}); 

  使用方式有两种,一种是直接在页面里:

<p>{{now | date : ‘yyyy-MM-dd‘}}</p>

 一种是在 js 里面用:

// $filter(‘过滤器名称‘)(需要过滤的对象, 参数1, 参数2,...)
$filter(‘date‘)(now, ‘yyyy-MM-dd hh:mm:ss‘);

  

5. factory和service,provider是什么关系?

factory 把 service 的方法和数据放在一个对象里,并返回这个对象;service 通过构造函数方式创建 service,返回一个实例化对象;provider 创建一个可通过 config 配置的 service。

从底层实现上来看,service 调用了 factory,返回其实例;factory 调用了 provider,将其定义的内容放在 $get 中返回。factory 和 service 功能类似,只不过 factory 是普通 function,可以返回任何东西(return 的都可以被访问,所以那些私有变量怎么写你懂的);service 是构造器,可以不返回(绑定到 this 的都可以被访问);provider 是加强版 factory,返回一个可配置的 factory。
1. angular的数据绑定采用什么机制?详述原理

脏检查机制。

Angular 在 scope 模型上设置了一个监听队列,用来监听数据变化并更新 view 。每次绑定一个东西到 view 上时 AngularJS 就会往 $watch 队列里插入一条 $watch,用来检测它监视的 model 里是否有变化的东西。当浏览器接收到可以被 angular context 处理的事件时,$digest 循环就会触发,遍历所有的 $watch,最后更新 dom。
举个栗子:
<button ng-click="val=val+1">increase 1</button>

  

click 时会产生一次更新的操作(至少触发两次 $digest 循环)

  • 按下按钮
  • 浏览器接收到一个事件,进入到 angular context
  • $digest 循环开始执行,查询每个 $watch 是否变化
  • 由于监视 $scope.val 的 $watch 报告了变化,因此强制再执行一次 $digest 循环
  • 新的 $digest 循环未检测到变化
  • 浏览器拿回控制器,更新 $scope.val 新值对应的 dom

$digest 循环的上限是 10 次(超过 10次后抛出一个异常,防止无限循环)。

2. 两个平级界面块a和b,如果a中触发一个事件,有哪些方式能让b知道,详述原理


这个问题换一种说法就是,如何在平级界面模块间进行通信。有两种方法,一种是共用服务,一种是基于事件。


a. 共用服务


在 Angular 中,通过 factory 可以生成一个单例对象,在需要通信的模块 a 和 b 中注入这个对象即可。


b. 基于事件


这个又分两种方式


第一种是借助父 controller。在子 controller 中向父 controller 触发($emit)一个事件,然后在父 controller 中监听($on)事件,再广播($broadcast)给子 controller ,这样通过事件携带的参数,实现了数据经过父 controller,在同级 controller 之间传播。


第二种是借助 $rootScope。每个 Angular 应用默认有一个根作用域 $rootScope, 根作用域位于最顶层,从它往下挂着各级作用域。所以,如果子控制器直接使用 $rootScope 广播和接收事件,那么就可实现同级之间的通信。

angular应用常用哪些路由库,各自的区别是什么?


Angular1.x 中常用 ngRoute 和 ui.router,还有一种为 Angular2 设计的 new router(面向组件)。后面那个没在实际项目中用过,就不讲了。


无论是 ngRoute 还是 ui.router,作为框架额外的附加功能,都必须以 模块依赖 的形式被引入。


两者区别是:


ngRoute 模块是 Angular 自带的路由模块,而 ui.router 模块是基于 ngRoute模块开发的第三方模块。


ui.router 是基于 state (状态)的, ngRoute 是基于 url 的,ui.router模块具有更强大的功能,主要体现在视图的嵌套方面。


使用 ui.router 能够定义有明确父子关系的路由,并通过 ui-view 指令将子路由模版插入到父路由模板的 <div ui-view></div> 中去,从而实现视图嵌套。而在 ngRoute 中不能这样定义,如果同时在父子视图中 使用了 <div ng-view></div> 会陷入死循环。


5. 如果通过angular的directive规划一套全组件化体系,可能遇到哪些挑战?


没有自己用 directive 做过一全套组件,讲不出。


能想到的一点是,组件如何与外界进行数据的交互,以及如何通过简单的配置就能使用吧。


6. 分属不同团队进行开发的angular应用,如果要做整合,可能会遇到哪些问题,如何解决?

可能会遇到不同模块之间的冲突。比如一个团队所有的开发在 moduleA 下进行,另一团队开发的代码在 moduleB 下:
angular.module(‘myApp.moduleA‘, [])
    .factory(‘serviceA‘, function(){
        ...
    })

angular.module(‘myApp.moduleB‘, [])
    .factory(‘serviceA‘, function(){
        ...
    })    

angular.module(‘myApp‘, [‘myApp.moduleA‘, ‘myApp.moduleB‘]) 

  

7. angular的缺点有哪些?


a. 强约束


导致学习成本较高,对前端不友好。


但遵守 AngularJS 的约定时,生产力会很高,对 Java 程序员友好。


b. 不利于 SEO


因为所有内容都是动态获取并渲染生成的,搜索引擎没法爬取。


一种解决办法是,对于正常用户的访问,服务器响应 AngularJS 应用的内容;对于搜索引擎的访问,则响应专门针对 SEO 的HTML页面。


c. 性能问题


作为 MVVM 框架,因为实现了数据的双向绑定,对于大数组、复杂对象会存在性能问题。

可以用来 优化 Angular 应用的性能 的办法:


  • 减少监控项(比如对不会变化的数据采用单向绑定)
  • 主动设置索引(指定 track by,简单类型默认用自身当索引,对象默认使用 $$hashKey,比如改为track by item.id)
  • 降低渲染数据量(比如分页,或者每次取一小部分数据,根据需要再取)
  • 数据扁平化(比如对于树状结构,使用扁平化结构,构建一个 map 和树状数据,对树操作时,由于跟扁平数据同一引用,树状数据变更会同步到原始的扁平数据)

    9. 详述angular的“依赖注入”


    AngularJS 是通过构造函数的参数名字来推断依赖服务名称的,通过 toString() 来找到这个定义的 function 对应的字符串,然后用正则解析出其中的参数(依赖项),再去依赖映射中取到对应的依赖,实例化之后传入。


    因为 AngularJS 的 injector 是假设函数的参数名就是依赖的名字,然后去查找依赖项,那如果像下面这样简单注入依赖,代码压缩后(参数被重命名了),就无法查找到依赖项了。

    function myCtrl = ($scope, $http){
        ...
    }
    

      

    所以,通常会使用下面两种方式注入依赖(对依赖添加的顺序有要求)。

     

    数组注释法:

    myApp.controller(‘myCtrl‘, [‘$scope‘, ‘$http‘, function($scope, $http){
        ...
    }])
    

      显式 $inject :

    myApp.controller(‘myCtrl‘, myCtrl);
    function myCtrl = ($scope, $http){
        ...
    }
    myCtrl.$inject = [‘$scope‘, ‘$http‘];
    

      

    对于一个 DI 容器,必须具备三个要素:依赖项的注册,依赖关系的声明和对象的获取。在 AngularJS 中,module 和 $provide 都可以提供依赖项的注册;内置的 injector 可以获取对象(自动完成依赖注入);依赖关系的声明,就是上面的那两种方式。

如何权衡自己的angular水准

标签:模块开发   函数   app   优化   强制   direct   filter   自定义   树状   

原文地址:http://www.cnblogs.com/fangshidaima/p/6017207.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!