AngularJS:使用 $compile 将 html 附加到网页

Posted

技术标签:

【中文标题】AngularJS:使用 $compile 将 html 附加到网页【英文标题】:AngularJS: Using $compile to append html to a web page 【发布时间】:2015-10-15 04:29:24 【问题描述】:

我有一个动态网页,它是由用户之前的条目生成的。这意味着遍历他们可以选择的可能输入列表,然后将它们附加到指令中的 html

为了让我的 ng- 标签都能正常工作,我需要通过 $compile 运行这一大块 html,这样它们才能正常工作。这一直很好,我现在的问题是我正在尝试做更复杂的字段,这些字段使用自定义指令或 jquery 类,这些字段在通过 $compile 后拒绝正常运行。

例如——

<div data-j-signature="obj.Test" data-pen-color="#0000ff" data-line-color="#00000" style="border:1px #000 solid;"></div><div class="col-sm-11">

这使用了一个使用良好的名为 JSignature 的 Angular 库,当放在我的网页中某处时可以正常工作,但在编译过程中却不行。

我不一定要为该特定问题寻找答案,因为我觉得这将是我尝试添加的更多字段的持续问题。有没有人对如何解决这个问题有任何一般性建议?有没有我没有看到的替代方案?

这是我的 html -

<div ng-repeat="Question in Questions">
    <question-type></question-type>
</div>

这是我的指令在将大量 html 字符串组合在一起后最后所做的重要部分 -

var compiledHtml = $compile(stringOfHtml)(scope);
element.append(compiledHtml);

【问题讨论】:

谁创建了 datepicker 实例?指令还是初始化脚本? 嗨,我从帖子中删除了日期选择器,因为我认为显示一个不起作用的角度示例更相关。 JSignature 也是 jQuery。如果你在它周围包裹一个指令,那可能期望元素已经存在于 DOM 中,但你在编译后插入它。 啊是的...我只是在考虑指令而不是库。再检查一下之后,它确实首先命中 jsignature 指令,然后在我的指令中编译,然后进入 jquery jsignature 库。您认为将编译延迟到最后是否可以解决这个问题? 【参考方案1】:

这使用 jquery datepicker 并且可以正常工作,但在附加然后在我的指令中编译时不能正常工作。

这确实是您问题的核心。你不能指望 jQuery 插件在 Angular 应用程序中正常工作,仅仅因为它们的生命周期不是很好的重合。我会解释得更好。

当您运行应用程序时,一些带有指令和绑定 Angular 的 HTML 会被 Angular 解析和编译。我很好。此时,您的 jQuery 插件甚至可能会正确初始化,因为它们通常只需要渲染 DOM。但是,当您附加新编译的动态 HTML 时会发生什么? Angular 会很好地接受它,因为您调用了$compile。但是 jQuery 可能会去同步化并且永远不会重新初始化插件。

这就是为什么你不应该像我们都习惯的那样使用 jQuery 的主要原因。理想情况下,jQuery 的使用(以及一般的 DOM 操作)应该仅限于自定义指令。这是 100% 确保 Angular 和 jQuery 都在正确的时刻更新/初始化它们的东西的唯一方法。

所以.. 你需要一个日期选择器吗?伟大的!有许多可用的 Angular 指令(例如,Angular UI datepicker)简单地将 jQuery 插件包装到链接函数中,从而使其与 Angular 工作流和摘要循环兼容。

【讨论】:

感谢您的信息。我确实计划摆脱 jquery,所以也许我应该只使用一个不起作用的角度示例,我会更新我的帖子。 如果您有任何其他建议,请编辑我的帖子 :)【参考方案2】:

app.controller('mainController', function($scope, $http, $compile)
$scope.updateData = function()
    $http(
      method: "POST",
      url: 'abc.com',
      data: angular.element('#form').serialize(),
      headers : 'Content-Type': 'application/x-www-form-urlencoded'
    ).
    then(function(result)
        var temp = $compile(result.data)($scope);
        angular.element('#showhtml').html(temp);
    ).catch(function(response)
    ).finally(function() 
    );

);

【讨论】:

以上是关于AngularJS:使用 $compile 将 html 附加到网页的主要内容,如果未能解决你的问题,请参考以下文章

angularjs指令中的compile详解

AngularJS指令中的compile与link函数解析

AngularJS学习之compile与link函数详解

angularjs指令中的compile与link函数详解补充

angularjs link compile与controller的区别详解,了解angular生命周期

将 AngularJs 1.5 升级到 1.6 - $compile reg 控制器实例的更改会影响哪些确切的绑定?