84

我正在使用 jQuery 和 AngularJS 开发 Ajax 应用程序。

当我使用 jQuery 的函数更新 div 的内容(包含 AngularJS 绑定)时html,AngularJS 绑定不起作用。

以下是我正在尝试做的代码:

$(document).ready(function() {
  $("#refreshButton").click(function() {
    $("#dynamicContent").html("<button ng-click='count = count + 1' ng-init='count=0'>Increment</button><span>count: {{count}} </span>")
  });
});
</style><script src="http://docs.angularjs.org/angular-1.0.1.min.js"></script><style>.ng-invalid {
  border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="">
  <div id='dynamicContent'>
    <button ng-click="count = count + 1" ng-init="count=0">
        Increment
      </button>
    <span>count: {{count}} </span>
  </div>


  <button id='refreshButton'>
    Refresh
  </button>
</div>

我在 ID 的 div 中有动态内容#dynamicContent,并且我有一个刷新按钮,当单击刷新时会更新此 div 的内容。如果我不刷新内容,增量会按预期工作,但在我刷新后,AngularJS 绑定停止工作。

这在 AngularJS 中可能无效,但我最初使用 jQuery 构建应用程序,后来开始使用 AngularJS,所以我无法将所有内容迁移到 AngularJS。非常感谢任何帮助在 AngularJS 中工作的帮助。

4

3 回答 3

115

您需要$compile在将 HTML 字符串插入 DOM 之前调用它,以便 Angular 有机会执行绑定。

在你的小提琴中,它看起来像这样。

$("#dynamicContent").html(
  $compile(
    "<button ng-click='count = count + 1' ng-init='count=0'>Increment</button><span>count: {{count}} </span>"
  )(scope)
);

显然,$compile必须将其注入您的控制器才能使其正常工作。

$compile在文档中阅读更多内容。

于 2012-08-02T15:17:33.460 回答
57

万一您无法控制动态内容的另一种解决方案

如果您没有通过指令加载元素(即,如注释 jsfiddles 中的示例),则此方法有效。

总结您的内容

将您的内容包装在 div 中,以便在使用JQuery时可以选择它。您还可以选择使用本机 javascript 来获取您的元素。

<div class="selector">
    <grid-filter columnname="LastNameFirstName" gridname="HomeGrid"></grid-filter>
</div>

使用角度注入器

如果您没有 $compile,您可以使用以下代码获取对 $compile 的引用。

$(".selector").each(function () {
    var content = $(this);
    angular.element(document).injector().invoke(function($compile) {
        var scope = angular.element(content).scope();
        $compile(content)(scope);
    });
});

概括

原始帖子似乎假设您有一个方便的 $compile 参考。当您有参考资料时,这显然很容易,但我没有,所以这就是我的答案。

前面代码的一个警告

如果您使用带有 minify 场景的 asp.net/mvc 包,则在发布模式下部署时会遇到麻烦。问题以 Uncaught Error: [$injector:unpr] 的形式出现,这是由 minifier 与 angular javascript 代码混淆引起的。

以下是补救方法

用以下重载替换前面的代码片段。

...
angular.element(document).injector().invoke(
[
    "$compile", function($compile) {
        var scope = angular.element(content).scope();
        $compile(content)(scope);
    }
]);
...

在我把它拼凑起来之前,这给我带来了很多悲伤。

于 2014-06-05T11:15:07.843 回答
18

除了@jwize 的回答

因为angular.element(document).injector()给出了错误injector is not defined 所以,我创建了可以在 AJAX 调用之后或使用 jQuery 更改 DOM 时运行的函数。

  function compileAngularElement( elSelector) {

        var elSelector = (typeof elSelector == 'string') ? elSelector : null ;  
            // The new element to be added
        if (elSelector != null ) {
            var $div = $( elSelector );

                // The parent of the new element
                var $target = $("[ng-app]");

              angular.element($target).injector().invoke(['$compile', function ($compile) {
                        var $scope = angular.element($target).scope();
                        $compile($div)($scope);
                        // Finally, refresh the watch expressions in the new element
                        $scope.$apply();
                    }]);
            }

        }

通过只传递新元素的选择器来使用它。像这样

compileAngularElement( '.user' ) ; 
于 2015-11-05T07:26:26.340 回答