angular 零碎

相关链接

作用域

  angular 中作用域的概念是一个亮点,由不同的指令、controller等作用域组成的作用域树就是一个app。简单理解一个controller的作用域就是一个$scope,在此controller下的所有指令的操作都是在此作用域下,ng-click,ng-show/hide/if 等指令的表达式计算就是在此作用域下进行的。作用域的层级结构使其具有了继承的特性,形成了作用域链,子作用域可以访问父作用域中的内容。

双向绑定原理

  angular的双向数据绑定是其核心功能。angular 通过监控能事件改变进行绑定;DOM事件(input改变,点击等),XHR的响应触发回调;浏览器地址变化,计时器触发回调等;如果以上情况没有发生,MV改变的可能性不大;当发生了能引起view或model改变的事件时angular就会从根作用域执行脏循环$digest检查,判断是否有需要改变的地方。脏循环会不止一次的执行,以便将所有的model改变集中在一起去改变view,为的是提高性能。

服务

  所谓服务就是一些可以共用的方法、常量等,注册之后可以在需要使用的地方通过名称进行依赖注入.在运行之前可以通过module进行注册服务

 apm = angular.module('apm', ['ngExtend', 'ui.router', 'highcharts-ng']);
    //常量  基本页面路径
    apm.constant('BASE_PATH', '/asset/views/')
        .constant('SUB_ROUTES', 'subroutes/');

  在运行阶段可以通过$provide进行注册,$provide只能在配置阶段注入,所以要在配置阶段保存其引用

 

 apm.config(function ($stateProvider, BASE_PATH, SUB_ROUTES, $controllerProvider, $filterProvider, $requireProvider, $urlRouterProvider, $provide) {
         apm.register = {
             controller: $controllerProvider.register,
             filter: $filterProvider.register,
             factory: $provide.factory
         };
 //具体使用
 apm.register.factory('overview_queryTransactions', function (MyChart, $myhttp, CHART_CONSTANT, $rootScope) 

 

  注册服务的方法比较

  对象种类 可以在配置阶段注入 可以在运行阶段注入
constant 常量值 Y
value 变量值 N Y
service 构造函数创建新对象 N Y
factory 工厂函数返回新对象 N Y
provider $get工厂函数返回新对象 Y N

依赖注入

  angular会将依赖的所有模块上的所有服务混入应用级别的单一命名空间内。所以,模块间可以相互依赖,不同模块间的服务可以相互依赖。这有一个问题就是会存在冲突的可能性。在需要使用的地方根据名称注入。对应的每个名字只存在唯一的服务。我们利用这点可以在依赖某模块的同时去覆盖此模块提供的服务。

   注入服务

 var c = $injector.get(cfg.chartId, cfg.header);

事件传播机制

  angular的事件传播机制类似DOM中的冒泡与捕获的情形。在子级可以通过$scope.$emit 进行事件冒泡,父级可以收到此事件,父级通过$scope.$broadcast进行广播,所有子级可以收到此事件.

            //监听事件
            $rootScope.$on(EVENT.MODULE.emit, function (event, data) {
                $rootScope.$broadcast(EVENT.MODULE.broadcast, data);
            }); 
           //触发事件
            $scope.$emit(EVENT.CHANGE_CONDITION.emit, null);        

路由

  angular用于开发单页面应用,路由是必不可少的。angular自带路由模块,比较简单的路由需求是可以满足了。存在一些局限。不支持嵌套路由,一个路由只能对应页面中一个区域。当你遇到这些问题的时候,已经有人帮你解决了,ui-router,目前还没遇到过他不支持的功能;

 

 $urlRouterProvider.when(/^/?$/, '/app/application/application/application');

        $stateProvider
            //固定路径配置示例
            //.state('accountsettings', {//账号设置
            //    url: '/accountsettings',
            //    templateUrl: BASE_PATH + 'account_settings.html',
            //    resolve: {
            //        require: $requireProvider.require('account_settings'),
            //    }
            //})
            //默认规则配置
            .state('def', {
                url: '{url:[^@]*}',//'/{one_code:\w+}/{two_code:\w+}/{three_code:\w+}/{url:[^@]*}',
                templateUrl: function ($stateParams) {
                    var menu = apm.parseURL($stateParams.url), url = BASE_PATH + menu.path;
                    return addSuffix(url);
                },
                resolve: {
                    require: function ($q, $stateParams) {
                        return resolve($q, $stateParams.url, [getDeps($stateParams.url)]);
                    }
                }
            })
            //子路由
            .state('def.child', {
                url: '@/{path:[^/]+}{a1:/?}{p1:[^/]*}{a2:/?}{p2:[^/]*}{a3:/?}{p3:[^/]*}{a4:/?}{p4:[^/]*}{a5:/?}{p5:[^/]*}',
                templateUrl: function ($stateParams) {
                    var url = BASE_PATH + SUB_ROUTES + $stateParams.path;
                    return addSuffix(url);
                },
                resolve: {
                    require: function ($q, $stateParams) {
                        return resolve($q, $stateParams.path, [SUB_ROUTES + $stateParams.path.split(/[.?]/)[0]]);
                    }
                }
            });
    })

 

  ui-router 跳转带参数的url  api

.state('/search', { //搜索
    url: '/search?query',
。。。
$state.go('/search',{query:$scope.searchfield});

 

异步加载

  angular开发单页面应用的时候不可能一次将所有资源全部加载,通常会整合requirejs;

  

//配置路由
$stateProvider.state('index', { //首页
            url: '/index',
            templateUrl: '/index',
            resolve: {
                require: $requireProvider.require('index')
            }
        })

 angular.module('ngExtend', ['ng', 'ngCookies']).
        provider('$require', function rq() {
            /**
             * 异步加载配置
             * @param deps 如果是单个依赖可以直接写名字,多个依赖使用数组,路径根据require配置
             * @returns {*}
             */
            this.require = function (deps) {
                if (angular.isString(deps)) {
                    deps = [deps];
                }
                return ['$rootScope', '$q', function ($rootScope, $q) {
                    var def = $q.defer();
                    require(deps, function () {
                        $rootScope.$apply(function () {
                            def.resolve();
                        });
                    });
                    return def.promise;
                }];
            };

            this.$get = function () {
                return this;
            };
        }).

 

  需要手动启动angular

 angular.element(document).ready(function () {
        //阻止 # 导航
        $(document).delegate('a', 'click', function (event) {
            var href = $(this).attr('href');
            if (href === '#') {
                event.preventDefault();
            }
        });
        angular.bootstrap(document, ['apm']);
    });

 

controller之间相互通信

  • 通过上面的事件传播机制
  • 父作用域数据共享
  • url参数传递 

  推荐事件传播以及url传递,url传递参数可以刷新

  

Form验证

   任意元素上(form元素好像不好使)通过ng-form="formname" 指定一个form, 在此元素内的input元素通过指定name属性就可以在绑定到form作用域上
    表单验证,最常使用 ng-minlength,mg-maxlength,ng-pattern="/^d?$/",表单及单个验证元素上都有 $valid,$invalid,$pristine,$dirty ,select标签 pattern无效,只要选择了option就是验证通过的
     
 <input type="email" class="form-control" placeholder="" ng-model="condition.email"
                                           name="email"
                                           ng-required="requiredEmail"
                                           ng-class="{'border-red':editform.email.$invalid}" ng-if="isEdit" disabled>

更改插值表达式

myMod.config(function($interpolateProvider){
        $interpolateProvider.startSymbol(‘[[’);
        $interpolateProvider.endSymbol(‘]]’);
})

表达式

 // 取值 var modelGetter = $parse($ipt.attr('ng-model'));
// 设值  var modelSetter = modelGetter.assign;
//执行  $scope.$eval

动态编译指令

  参考

element.append($compile(html.join(' '))(scope));

 测试

测试环境 karma+jasmine 依赖node.js

 
参考 网页:
    karma+jasmine 配置
 
    karma 插件
 
    jasmine
 
 
  1、全局安装karma
       npm install -g karma (有可能提示net framework 没有安装,不用管,安装之后验证一下是否成功karma start)
       npm install -g karma-jasmine 
       npm install -g karma-chrome-launcher
   
   2.jasmine 测试nodejs

 

 

原文地址:https://www.cnblogs.com/vvch/p/4864154.html