Angular VARIED, database-dependent callback after render
Angular VARIED, database-dependent callback after render
在我的博客上,我希望能够有特定于每篇文章的交互式演示。因此,每篇文章既有其内容,又有示例演示,这些演示是要呈现到页面上的HTML。
到目前为止,没有问题。我创建了一个render_html指令:
angular.module("RenderHtml", []).directive("renderHtml", () -> { restrict: "A", scope: { renderHtml: "@" }, link: (scope, element, attrs) -> { scope.$watch("renderHtml", (newVal) -> { element.html(newVal); }); } });
我这样调用它:
问题是,我希望这个HTML中嵌入并执行Angular代码。
因此,呈现的示例HTML将类似于:
Etc
当页面呈现时,SpecificExampleCtrl将被加载,其init函数将运行,并且在点击该链接时,ng-click将运行。
(我已经接受了,即使我设法让它工作,也必须将ng_controller保存在应用程序中,但如果有人能想出一种在数据库中保存它的方法,我会非常高兴。)
总之,我的问题似乎与[这个](https://stackoverflow.com/questions/11953348/angularjs-callback-after-render-work-with-dom-after-render)和其他问题不同。
为了澄清我已经完成了什么 - HTML被呈现为HTML,但其中的Angular代码没有运行,尽管被调用的控制器在我的应用程序中存在。
对建议的回应中的编辑
angular.module("RenderHtml", []).directive("renderHtml", ($compile) -> { restrict: "A", scope: { renderHtml: "@" }, link: (scope, element, attrs) -> { scope.$watch("renderHtml", (newVal) -> { element.html(newVal); $compile(eval(element)); }); } });
(上述代码无法正常工作。它会呈现HTML,但不会评估Angular代码。)
编辑看起来我应该使用$eval而不是原始的eval,但是当我尝试在指令中注入它或调用它而不进行注入时,网站出错了,当我注入并使用类似功能的$parse时,整个Angular模板都没有呈现,也没有出现错误。
答案
最终这个方案可行:
angular.module("RenderHtml", []).directive("renderHtml", ($compile) -> { restrict: "A", scope: { renderHtml: "@" }, link: (scope, element, attrs) -> { scope.$watch("renderHtml", (newVal) -> { linkFunc = $compile(newVal); element.html(linkFunc(scope)); }); } });
编译HTML返回一个使用作用域作为参数的函数。
问题出现的原因是在Angular中,当从数据库中获取的javascript代码需要在渲染后执行时,需要使用eval函数来将其编译。这种方法不太安全,如果存在用户输入的可能性,则不建议使用,因为代码将在用户的环境中执行。
解决方法是使用eval函数来编译从数据库中获取的javascript代码。然后,需要使用$compile函数来编译HTML。最后,使用$injector来在作用域上调用控制器函数。
在指令中,使用link函数来编译HTML和执行控制器函数。通过$watch函数监视scope.$eval(attrs.compile)的变化,并在变化时更新元素的内容并编译内容。同样地,使用$watch函数监视scope.$eval(attrs.compileCode)的变化,并在变化时执行eval函数获取控制器对象,然后使用$injector.invoke函数在子作用域上调用控制器函数。
在HTML中,使用compile指令来指定要编译的HTML和要执行的控制器代码。
在控制器中,定义simulateAjax函数来模拟从数据库获取HTML和控制器代码的过程,并将其赋值给$scope.html和$scope.js。
以上是解决问题的方法,其中指令代码和HTML代码已经给出,可以直接使用。