AngularJS + JQuery:如何在 angularjs 中获取动态内容
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11771513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AngularJS + JQuery : How to get dynamic content working in angularjs
提问by Raja
I am working on a Ajax app using both jQuery and AngularJS.
我正在使用 jQuery 和 AngularJS 开发 Ajax 应用程序。
When I update content (which contains AngularJS bindings) of a div using jQuery's html
function, the AngularJS bindings doesn't work.
当我使用 jQuery 的html
函数更新 div 的内容(包含 AngularJS 绑定)时,AngularJS 绑定不起作用。
Following is code of what I am trying to do:
以下是我正在尝试做的代码:
$(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>
I have dynamic content inside a div with the ID #dynamicContent
, and I have a refresh button that would update contents of this div when refresh is clicked. Increment works as expected if I don't refresh the content, but after I refresh, the AngularJS binding stops working.
我在一个带有 ID 的 div 中有动态内容#dynamicContent
,并且我有一个刷新按钮,可以在单击刷新时更新此 div 的内容。如果我不刷新内容,增量会按预期工作,但刷新后,AngularJS 绑定停止工作。
This may not be valid in AngularJS, but I initially built application with jQuery and started using AngularJS later on so I can't migrate everything to AngularJS. Any help with getting this working in AngularJS is greatly appreciated.
这在 AngularJS 中可能无效,但我最初使用 jQuery 构建应用程序,后来开始使用 AngularJS,因此我无法将所有内容迁移到 AngularJS。非常感谢在 AngularJS 中获得此功能的任何帮助。
回答by Noah Freitas
You need to call $compile
on the HTML string before inserting it into the DOM so that angular gets a chance to perform the binding.
您需要$compile
在将 HTML 字符串插入到 DOM 之前调用它,以便 angular 有机会执行绑定。
In your fiddle, it would look something like this.
在你的小提琴中,它看起来像这样。
$("#dynamicContent").html(
$compile(
"<button ng-click='count = count + 1' ng-init='count=0'>Increment</button><span>count: {{count}} </span>"
)(scope)
);
Obviously, $compile
must be injected into your controller for this to work.
显然,$compile
必须注入您的控制器才能使其工作。
Read more in the $compile
documentation.
在$compile
文档中阅读更多内容。
回答by jwize
Another Solution in Case You Don't Have Control Over Dynamic Content
万一您无法控制动态内容的另一种解决方案
This works if you didn't load your element through a directive (ie. like in the example in the commented jsfiddles).
如果您没有通过指令加载您的元素(即,就像在评论的 jsfiddles 中的示例一样),这将起作用。
Wrap up Your Content
结束您的内容
Wrap your content in a div so that you can select it if you are using JQuery. You an also opt to use native javascript to get your element.
将您的内容包装在一个 div 中,以便您在使用JQuery 时可以选择它。您还可以选择使用本机 javascript 来获取您的元素。
<div class="selector">
<grid-filter columnname="LastNameFirstName" gridname="HomeGrid"></grid-filter>
</div>
Use Angular Injector
使用 Angular Injector
You can use the following code to get a reference to $compile if you don't have one.
如果您没有 $compile,您可以使用以下代码来获取对 $compile 的引用。
$(".selector").each(function () {
var content = $(this);
angular.element(document).injector().invoke(function($compile) {
var scope = angular.element(content).scope();
$compile(content)(scope);
});
});
Summary
概括
The original post seemed to assume you had a $compile reference handy. It is obviously easy when you have the reference, but I didn't so this was the answer for me.
最初的帖子似乎假设您有一个方便的 $compile 参考。当你有参考资料时,这显然很容易,但我没有,所以这就是我的答案。
One Caveat of the previous code
上一个代码的一个警告
If you are using a asp.net/mvc bundle with minify scenario you will get in trouble when you deploy in release mode. The trouble comes in the form of Uncaught Error: [$injector:unpr] which is caused by the minifier messing with the angular javascript code.
如果您使用带有 minify 场景的 asp.net/mvc 包,则在发布模式下部署时会遇到麻烦。问题以 Uncaught Error: [$injector:unpr] 的形式出现,这是由 minifier 与 angular javascript 代码混淆造成的。
Here is the way to remedy it:
这是补救的方法:
Replace the prevous code snippet with the following overload.
用以下重载替换前面的代码片段。
...
angular.element(document).injector().invoke(
[
"$compile", function($compile) {
var scope = angular.element(content).scope();
$compile(content)(scope);
}
]);
...
This caused a lot of grief for me before I pieced it together.
在我把它拼凑起来之前,这让我很伤心。
回答by shyammakwana.me
Addition to @jwize's answer
除了@jwize 的回答
Because angular.element(document).injector()
was giving error injector is not defined
So, I have created function that you can run after AJAX call or when DOM is changed using jQuery.
因为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();
}]);
}
}
use it by passing just new element's selector. like this
通过只传递新元素的选择器来使用它。像这样
compileAngularElement( '.user' ) ;