Javascript 使用Angular加载部分页面并编译控制器
在大规模应用程序中,我们的web应用程序可能被组织成单独的部分页面,以增加应用程序的模块化程度。在某些情况下,使用$http.get或JQuery$.load编译通过XHR或Ajax请求加载的部分页面将引入错误 以我的场景为例,我使用的正是Kohana PHP框架,因此我可以在服务器级别控制web应用程序的模块化。像往常一样,所有模板和页面都被分离到视图中,将所有HTML、JS和CSS放在表示层上 这将为我在客户端处理上实现Javascript MVW/MVC堆栈提供极大的灵活性,因为我的web应用程序在很大程度上依赖AJAX请求从后端应用程序获取数据。在我的场景中,我使用AngularJS,下面是一个简单的关于如何将模型中的数据呈现给客户端的伪脚本 Kohana模型>Kohana控制器>Kohana视图>XHR>JQuery\Angular>DOM 我在我的应用程序中的一部分,真的让我大吃一惊,让我喝几瓶新陈代谢饮料来解决这个应用程序。在这里,我有一个模式对话框,部分页面通过XHR从服务器加载并附加到选定的DOM 问题是,当Angular尝试编译部分页面时,当它找到ng控制器指令时,它将查找引用已处理指令的函数。由于DOM解析器尚未对控制器求值,因此未找到控制器时产生错误。但是,当您在加载部分页面之前在应用程序中的某个位置预加载函数时,一切都正常。下面是我如何设置对话框服务的示例,当我单击所述链接时,将从link指令调用该对话框服务Javascript 使用Angular加载部分页面并编译控制器,javascript,jquery,model-view-controller,dom,angularjs,Javascript,Jquery,Model View Controller,Dom,Angularjs,在大规模应用程序中,我们的web应用程序可能被组织成单独的部分页面,以增加应用程序的模块化程度。在某些情况下,使用$http.get或JQuery$.load编译通过XHR或Ajax请求加载的部分页面将引入错误 以我的场景为例,我使用的正是Kohana PHP框架,因此我可以在服务器级别控制web应用程序的模块化。像往常一样,所有模板和页面都被分离到视图中,将所有HTML、JS和CSS放在表示层上 这将为我在客户端处理上实现Javascript MVW/MVC堆栈提供极大的灵活性,因为我的web
var dialogService = angular.module('dialog.service', []);
dialogService.factory('Dialog', function($http,$compile){
var dialogService = {};
dialogService.load = function(url, scope){
$("#dialog:ui-dialog").dialog( "destroy" );
$("#dialog").attr('title','Atlantis');
$http.get(url).success(function (data) {
html = $compile(data)(scope);
$('#dialog-content').html(html);
$("#dialog").dialog({
width: '600px',
buttons: {
"Ok": function() {
$( this ).dialog( "close" );
return true;
},
},
close: function(){
if (typeof (onClose) == 'function') { onClose(); }
},
});
});
}
return dialogService;
});
经过一些研究,我找到了一些解决方案,并与其他像我这样的初学者分享了我的答案。(对不起我的英语)。AngularJS在这个设置上没有错,其他JS大师可能已经知道解决方案,并且在发明另一个很酷的web开发工具或框架时,非常忙地与我们分享。没关系,继续这样做。这可能不是一个很酷或最后通牒的解决方案,请与我们分享任何改进或提示 为了克服这个问题,我们需要一个策略来设置,让我从一个示例代码开始,这样我们的大脑在信息流动时会进行消化。下面的代码是我使用JQuery创建模式对话框的占位符,Ajax内容将被插入
<div ng-app="asng" id="dialog" title="" style="display:none">
<div id="dialog-content"></div>
</div>
上面的第一行将在数据变量中编译DOM,并插入根DOM。不幸的是,第一行将显示一个错误:找不到控制器事务
发生这种情况的原因是,部分页面中的脚本块尚未由DOMP解析器计算,因为它没有插入到根DOMP中。现在您看到了指示灯OK,因此我们必须稍微更改编译策略,插入新的DOM,然后我们将解析回插入的DOM外观示例如下:-
html = $('#dialog-content').html(data);
$compile(html)(scope);
超薄而简单的解决方案,我花了几个早上才解决了这个问题,只是因为忽略了DOM解析的简单概念。如果我理解您的意图,下面是一个简单的示例 我想通过AJAX发布到Django表单,然后用返回的标记替换页面中的表单内容。返回的标记包括一个ng控制器,我需要在加载时执行该控制器:
.controller('MyForm', function($element, $compile, $scope){
var scope = $scope;
var $theForm = $element;
var $formBlock = $element.find('.the_form'); // is replaced by the form response
$element.find('.submit_the_form').click(function(){
// submit the form and replace contents of $formBlock
$.post($theForm.attr('action'), $theForm.serialize(), function(response){
var newstuff = $formBlock.html(response);
$compile(newstuff)(scope); // loads the angular stuff in the new markup
});
});
})
我认为您感兴趣的行是$compile(newstuff)(scope)
编辑:
天啊,今天早上用其他标记尝试了一下,但没有效果,我也弄不明白为什么。事实证明,如果我没有在新标记中指定带有ng模型的字段,那么$compile就不会执行。增加:
<input type="hidden" name="dummy" value="0" ng-model="dummy"/>
…现在它可以编译了。我尝试使用这种方法,但它告诉我$compile没有定义,我需要添加其他东西吗?我需要知道如何初始化AngularJS,您可以在JsFiddle上共享吗?通过查看您的代码,我不知道您的代码如何工作,但这可能是因为加载js的方式。你使用过脚本加载器吗?在运行应用程序控制器之前,您应该验证是否加载了AngularJS。是否有人提供了这方面的具体示例?我在本文中也有类似的问题,因此:
.controller('MyForm', function($element, $compile, $scope){
var scope = $scope;
var $theForm = $element;
var $formBlock = $element.find('.the_form'); // is replaced by the form response
$element.find('.submit_the_form').click(function(){
// submit the form and replace contents of $formBlock
$.post($theForm.attr('action'), $theForm.serialize(), function(response){
var newstuff = $formBlock.html(response);
$compile(newstuff)(scope); // loads the angular stuff in the new markup
});
});
})
<input type="hidden" name="dummy" value="0" ng-model="dummy"/>