6

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

对于一个简单的场景,假设我将以下 HTML AJAX 转换为页面。还假设该页面已经包含了 Angular.js。我可以调用什么来使以下行为像 Angular 应用程序?

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

谢谢

4

3 回答 3

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();
  });
于 2013-09-18T14:08:22.210 回答
2

手动初始化工作得很好

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

我最终遇到了 gem rack-pjax 的一些问题,因为它在我的 url 中转义了小胡子,所以我只是摆脱了中间件并决定让 Web 服务器检测请求中的 pjax 并选择退出渲染布局。

于 2012-10-14T23:13:46.017 回答
-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 调用会替换整个正文。

于 2016-03-23T10:31:31.553 回答