理解angularJS的逐步手动自举

时间:2016-05-20 10:36:20

标签: angularjs bootstrapping

我正在阅读angularJS的基础知识,了解它是如何手动引导的。我遇到了不同的方法,发现this approach最适合。

angular.element(document).ready(function(){
   angular.bootstrap(document,['myapp'])
})

走得更远,我遇到了this another way which breaks it to basics。我根据我的理解对代码进行了评论,但有人可以向我解释有关如何在幕后工作的更多细节。

window.onload = function (){

  var $rootElement = angular.element(window.document);
  var modules = [
    'ng',       // angular module
    'myApp',    // custom module
    // what are we trying to achieve here?
    function($provide){ 
        $provide.value('$rootElement',$rootElement)
    }
  ];

  var $injector = angular.injector(modules);      // one injector per application
  var $compile = $injector.get('$compile');       // Compile Service: it traverses the DOM and look for directives and  compile and return linking function. No accecess to scope
  var compositeLinkFn = $compile($rootElement);   // collection of all linking function. Here scope is getting accessed

  var $rootScope = $injector.get('$rootScope');   // Hold of the rootscope
  compositeLinkFn($rootScope);

  $rootScope.$apply();
}

此外,请通过提出更多方法和改进,随时向我提供更多有关此主题的信息。

1 个答案:

答案 0 :(得分:11)

  

我们想在这里实现什么目标?

var modules = [
    'ng',       // angular module
    'myApp',    // custom module
    function($provide){ 
        $provide.value('$rootElement',$rootElement)
    }
  ];

这与我们在angularjs中无处不在的旧依赖注入相同。 我们在这里注入模块ng并在其中注册value

最后我们将它传递给 angular.injector()

  var $injector = angular.injector(modules)

还是不相信?这是更简单的版本(我们在控制器中使用DI的方式)

var $injector = angular.injector(['ng','myApp',function($provide){
    $provide.value('$rootElement',$rootElement)
}])

现在有两个问题,

  1. 为什么我们使用angular.injector?

    因为,angular.injector创建了一个注入器对象,可用于检索服务以及依赖注入。我们需要这个来获取 $ compile 服务和范围的实例来绑定该模板。

  2. 我们为什么要设置$rootElement

    让angular知道应用程序的根元素。注意到documentangular.bootstrap(document,['myapp'])的使用情况?出于同样的原因。

    根据official documentation of $rootElement

      

    $ rootElement 是声明ngApp的元素或者   元素传递给angular.bootstrap。

    由于我们既没有使用ng-app也没有使用标准的angular.bootstrap方法,我们必须手动设置。

  3. 接下来,我们尝试从上一步收到的注入器实例中获取$compile服务。

    var $compile = $injector.get('$compile');
    

    $ compile服务是用于编译的服务。对标记调用$ compile将生成一个函数,您可以使用该函数将标记绑定到特定的范围(Angular调用链接函数)

    再次获取范围,我们使用$injector.get('$rootScope')并将其传递给我们从$ compile获得的复合链接函数。

    angular.bootstrap(document,[myApp])只是上述步骤的语法糖。它创建一个注入器实例,在它的帮助下设置相关服务,创建应用程序范围,最后编译模板。

    official documentation for angular.bootstrap可以看出这一点,它明确提到它会返回一个注入器实例。

      

    auto。$ injector 返回此应用的新创建的注入器

    official bootstrap guide

    中显示了相同的故事
      

    请注意,我们提供了要加载的应用程序模块的名称   进入注入器 作为angular.bootstrap的第二个参数   功能请注意,angular.bootstrap不会在上面创建模块   飞。您必须先创建任何自定义模块,然后才能将其作为传递   参数。

    最后,不用说..在加载HTML-Document并准备好DOM之后,所有这些都必须完成

    修改

    以下是此过程的图解表示。 angular.bootstrap process http://www.dotnet-tricks.com/Content/images/angularjs/bootstrap.png Image Reference

    希望有所帮助:)