zoukankan      html  css  js  c++  java
  • angularjs的启动方式

    最近一直在看angularjs的一些东西,因为项目的需要所以开始着手学习什么是angularjs。下面简单的记录一下angularjs的启动,来看看这个框架是如何启动工作的。

    我们在做简单的测试的时候通过下面的代码可以实现一个双向数据绑定的小例子:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <script src="libs/angular.js/1.4.6/angular.min.js"></script>
    </head>
    <body>
    
    <div ng-app="">
      <p>名字 : <input type="text" ng-model="name"></p>
      <h1>Hello {{name}}</h1>
    </div>
    
    </body>
    </html>
    View Code

    从代码中我们知道<div ng-app="">这个地方的ng-app并没有给赋值,这个时候我们的代码是可以正常调用起来的。

    我们试着去给ng-app赋值,暂且叫做myapp

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
    </head>
    <body>
    
    <div ng-app="myapp">
      <p>名字 : <input type="text" ng-model="name"></p>
      <h1>Hello {{name}}</h1>
    </div>
    
    </body>
    </html>
    View Code

    这个时候我们发现出现了无法解析表达式的界面

    于是我们猜想,是不是框架里不赋值的时候框架会自动的加载启动angularjs呢,而当我们真正的给它一个名字的时候我们需要手工的给它启动。

    然而当我们加上var myapp= angular.module("myapp",[]); 这句初期化的语句的时候,我们发现程序又可以正常的启动了。显然猜测是错误的。

    翻看源码后发现angularjs的源码里有一个叫做bootstrap()的方法,原来这就是启动angularjs的方法。根据这个方法我们总结如下:

    第一种情况:当页面元素中有ng-app或者是ng-app=""的时候,angularjs是可以自动启动的。

    第二种情况:当页面中的ng-app元素的内容被定义以后,我们可以通过var myapp= angular.module("myapp",[]);这种形式对它进行初期化,之后也是可以正常启动的。

    第三种情况:当页面中没有ng-app元素的时候,这个时候我们需要手动的启动angularjs了。手工启动的方法如下:

    <script>
        var myapp= angular.module("myapp",[]);
        angular.element(document).ready(function(){
           angular.bootstrap(document,['myapp']);
        });
    </script>
    View Code

    第四种情况:当页面中出现多个ng-app元素的时候,通常只会认识第一个元素,也很少有人会在一个html页面里定义两个ng-app,但是如果非要定义两个也可以采用第三种的方式手动启动第二个ng-app的入口。(当然正常的开发过程中没有人会这样给自己找麻烦的,显然把ng-app放到最外层,内容的业务交互完全可以交给Controller去处理)
    综上所述,我们明白了,原来在angularjs的启动过程中真正的门是一个叫做bootstrap的方法,var myapp= angular.module("myapp",[]);只是做个初期化并不是真正的启动方法。

    后面附上部分源码共参考

    function angularInit(element, bootstrap) {
      var appElement,
          module,
          config = {};
    
      // The element `element` has priority over any other element
      forEach(ngAttrPrefixes, function(prefix) {
        var name = prefix + 'app';
    
        if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
          appElement = element;
          module = element.getAttribute(name);
        }
      });
      forEach(ngAttrPrefixes, function(prefix) {
        var name = prefix + 'app';
        var candidate;
    
        if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\:') + ']'))) {
          appElement = candidate;
          module = candidate.getAttribute(name);
        }
      });
      if (appElement) {
        config.strictDi = getNgAttribute(appElement, "strict-di") !== null;
        bootstrap(appElement, module ? [module] : [], config);
      }
    }
    View Code
    function bootstrap(element, modules, config) {
      if (!isObject(config)) config = {};
      var defaultConfig = {
        strictDi: false
      };
      config = extend(defaultConfig, config);
      var doBootstrap = function() {
        element = jqLite(element);
    
        if (element.injector()) {
          var tag = (element[0] === window.document) ? 'document' : startingTag(element);
          //Encode angle brackets to prevent input from being sanitized to empty string #8683
          throw ngMinErr(
              'btstrpd',
              "App already bootstrapped with this element '{0}'",
              tag.replace(/</,'&lt;').replace(/>/,'&gt;'));
        }
    
        modules = modules || [];
        modules.unshift(['$provide', function($provide) {
          $provide.value('$rootElement', element);
        }]);
    
        if (config.debugInfoEnabled) {
          // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.
          modules.push(['$compileProvider', function($compileProvider) {
            $compileProvider.debugInfoEnabled(true);
          }]);
        }
    
        modules.unshift('ng');
        var injector = createInjector(modules, config.strictDi);
        injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
           function bootstrapApply(scope, element, compile, injector) {
            scope.$apply(function() {
              element.data('$injector', injector);
              compile(element)(scope);
            });
          }]
        );
        return injector;
      };
    
      var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;
      var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
    
      if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {
        config.debugInfoEnabled = true;
        window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');
      }
    
      if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
        return doBootstrap();
      }
    
      window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
      angular.resumeBootstrap = function(extraModules) {
        forEach(extraModules, function(module) {
          modules.push(module);
        });
        return doBootstrap();
      };
    
      if (isFunction(angular.resumeDeferredBootstrap)) {
        angular.resumeDeferredBootstrap();
      }
    }
    View Code
  • 相关阅读:
    解决跨操作系统平台JSON中文乱码问题
    httpencode编码
    DELPHI搭建centos开发环境
    cross socket和msgpack的数据序列和还原
    libmidas.so.2
    开发WINDOWS服务程序
    idhttp访问DATASNAP有密码验证的中间件
    接口操作XML
    HttpApplication中的异步线程
    Assembly类
  • 原文地址:https://www.cnblogs.com/xiaoxiaochengxuyuan/p/6144765.html
Copyright © 2011-2022 走看看