我有一个使用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>
由于
答案 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调用取代了整个身体。