AngularJS通过ajax加载问题

时间:2014-05-02 12:22:37

标签: javascript jquery ajax angularjs

在我的应用程序中,其中一个自定义小部件使用角度功能。

在其中一个页面中,它通过ajax呈现,即通过ajax获取以下内容并正确插入DOM:

_abc.html

<script type="text/javascript">console.log(1);</script>

<script type="text/javascript" src="/assets/angular.js"></script>
<script type="text/javascript">console.log(2);</script>

<script type="text/javascript" src="/assets/angular-ui-router.js"></script>
<script type="text/javascript">console.log(3);</script>

<script type="text/javascript" src="/assets/my_widget.js"></script>
<script type="text/javascript">console.log(4);</script>
<div class="ng-app: my_widget;" id="my_widget">
.....
.....
</div>

问题是: 当这个html通过ajax放入页面时,只打印出第一个控制台日志,而不是其他日志。 因此,在调用fetch angular.js之后没有调用任何东西,但是angular.js是通过ajax正确获取的,没有任何错误。

请注意,当上面的html直接放在页面加载而不是通过ajax时,一切都按预期工作正常。

1 个答案:

答案 0 :(得分:5)

以这种方式加载Angular小部件有几个问题:

  1. 您需要以正确的顺序和范围加载和执行_abc.html中定义的脚本;
  2. 您应该手动bootstrap Angular模块使其工作(因为ng-app仅适用于一个模块,并且仅触发文档就绪事件,因此它不适合动态加载的内容); < / LI>

    以下是我如何解决这些问题的示例(请参阅JavaScript部分中的评论)http://plnkr.co/edit/ClLvhvL5435yUKOHHO1U?p=preview

    <强>的index.html

    ...
    <div id="content"></div>
    ...
    

    <强>的JavaScript

    $(function() {
    
      function loadAngularPage(url, target) {
        $.ajax(url, {
          dataType: 'html',
          type: 'GET'
        }).done(function(data) {
          var el, div = document.createElement('div'); // Create detached HTML fragment 
          div.innerHTML = data; // Populate temporary detached fragment with received HTML
          function next() {
            if(el = div.firstChild) {
                target.appendChild(el);
                if(el.tagName === 'SCRIPT') {
                  if(el.hasAttribute('src')) {
                    $.getScript(el.getAttribute('src'), next); // Wait until script is loaded and executed and only then process next element
                  } else {
                    eval(el.innerHTML); // Evaluate embedded scripts
                    next();
                  }
                } else {
                  next();
                }
            } else {
              var match = /ng-app[:=]['"]?\s*([^;'" ]*)/gim.exec(target.innerHTML); // Get the name of angular's module to be bootstraped
              if(match && match.length === 2) {
                angular.bootstrap(target, [match[1]]); // bootstrap angular module
              }
            }
          }
          next(); // Start to process elements one by one
        });
      }
    
      loadAngularPage('_abc.html', document.getElementById('content')); // Load angular page
    
    });
    

    注意:注意/ng-app[:=]['"]?\s*([^;'" ]*)/不仅涵盖了ng-app在某个元素的class中定义的流程,还包括其他定义主角度模块的方法(如ng-appx-ng-appdata-ng-app属性等)。另外要注意Angular模块是在加载内容的容器内引导的,而不是在加载内容中的原始元素。

    <强> _abc.html

    <script type="text/javascript">console.log(1);</script>
    
    <script type="text/javascript" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
    <script type="text/javascript">console.log(2);</script>
    
    <script type="text/javascript" src="angular-ui-router.min.js"></script>
    <script type="text/javascript">console.log(3);</script>
    
    <script type="text/javascript" src="my_widget.js"></script>
    <script type="text/javascript">console.log(4);</script>
    
    <div class="ng-app: my_widget;" id="my_widget">
      Plain Text
      <div my-directive></div>
    </div>
    

    <强> my_widget.js

    angular.module('my_widget',['ui.router']).
      directive('myDirective', function() {
        return {
          template: '<div>My angular directive is working fine</div>'
        }
      });