主要是PJAX网站上有一些AngularJS

时间:2012-10-14 21:39:28

标签: angularjs pjax

我有一个使用PJAX的网站,我有一些使用AngularJS的网页。对于AngularJS页面,我想继续使用PJAX来获得与不重新加载整个HTML页面,资产等相关的所有好处。不幸的是,PJAX只是将一些HTML加载到页面中,并且不会触发任何javascript。这没关系,因为我可以在pjax成功时手动触发javascript,但我无法弄清楚是什么让AngularJS初始化。

对于一个简单的场景,让我说我将以下HTML AJAX写入页面。还假设,该页面已包含Angular.js。我可以称之为具有以下行为的角度应用程序吗?

<div>
  <label>Name:</label>
  <input type="text" ng-model="yourName" placeholder="Enter a name here">
  <hr>
  <h1>Hello {{yourName}}!</h1>
</div>

由于

3 个答案:

答案 0 :(得分:14)

angular.bootstrap(...)没有放弃为我工作,它正在抛出一个

  

已存在应用错误。

所以我选择(re)$compile解决方案,但是当从框架外部使用角度时,文档很稀疏(例如,如何调用$ compile)。经过大量的试验和错误这对我有用,虽然可能有一些开销:

  // outside of angular...
  var ngRefresh = function() {
    var scope = angular.element("body").scope();
    var compile = angular.element("body").injector().get('$compile');

    compile($("body").contents())(scope);
    scope.$apply();
  }

  // PJAX
  $('#page').on('pjax:success', function(e){
    ngRefresh();
  });

答案 1 :(得分:2)

手动初始化工作正常

  angular.element(document).ready(function() {
     angular.bootstrap(document);
   });

我最终遇到了gem rack-pjax的一些问题,因为它正在逃避我的网址中的胡须,所以我摆脱了中间件并决定让Web服务器在请求中检测到pjax并选择 - 在渲染布局之外。

答案 2 :(得分:-1)

从@charlysisto提供的解决方案开始,我在pjax:beforeReplace中添加了一个钩子来清理旧范围:

var cleanupRemovedScopes = function() {
  var $scope = angular.element("body").scope();

    var q = [$scope], scope, first = true;
    while (q.length > 0) {
        scope = q.pop();

        if (!first) {
            scope.$destroy();
        }

        first = false;

        if (scope.$$childHead) {
            q.push(scope.$$childHead);
        }

        if (scope.$$nextSibling) {
            q.push(scope.$$nextSibling);
        }
    }
}

$('#page').on('pjax:beforeReplace', function() {
  var $timeout = angular.element("body").injector().get("$timeout");
  $timeout(function() {
    cleanupRemovedScopes();
  }
}

然而,这个清理脚本的限制是,你的PJAX调用取代了整个身体。