• 如何权衡自己的angular水准


    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 可以获取对象(自动完成依赖注入);依赖关系的声明,就是上面的那两种方式。

  • 相关阅读:
    『中级篇』docker导学(一)
    计算机或许已经烂大街了,女生学计算机没出路吗?
    「初级篇」跟我一起学docker(17)--多节点mesos集群
    「初级篇」跟我一起学docker(18)--持续集成(初级终结篇)
    「初级篇」跟我一起学docker(16)--单节点mesos集群
    QT socket 多线程管理
    mysql数据库引擎 MyISAM和 InnoDB区别
    sql 删除表格delete drop truncate 区别(转)
    按层次遍历二叉树
    php基础排序算法 冒泡排序 选择排序 插入排序 归并排序 快速排序
  • 原文地址:https://www.cnblogs.com/fangshidaima/p/6017207.html
Copyright © 2020-2023  润新知