如何通过jQuery的.append()添加DOM元素(Angular指令)?
有没有什么办法来添加一个Angular指令的元素,像append()
这样的jQuery方法,并让Angular执行它的编译/链接,使其工作,就好像您将指令包含在第一位一样?
例:
app.directive('myAngularDirective', [function () { ... // Lots of stuff in here; works when used normally but not when added via jQuery }); $("body").append("<my-angular-directive />");
它目前只是附加了一个名为“my-angular-directive”的空DOM元素,但是Angular并没有踢入其中,而是发挥了魔力。
正确的做法是使用: $ compile ,如果您的指令返回: directive definition object
(也就是推荐的path),则可以调用它的link
函数(例如注入scope
)。
$('body').append($compile("<my-angular-directive />")(scope)); scope.$apply();
一个完整的例子,来自Angular文档 :
// Angular boilerplate var app = angular.module("myApp", []); app.controller("MyCtrl", function($scope) { $scope.content = { label: "hello, world!", }; }); // Wrap the example in a timeout so it doesn't get executed when Angular // is first started. setTimeout(function() { // The new element to be added var $div = $("<div ng-controller='MyCtrl'>new: {{content.label}}</div>"); // The parent of the new element var $target = $("[ng-app]"); angular.element($target).injector().invoke(function($compile) { var $scope = angular.element($target).scope(); $target.append($compile($div)($scope)); // Finally, refresh the watch expressions in the new element $scope.$apply(); }); }, 100);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div ng-app="myApp"> <div ng-controller="MyCtrl">old: {{content.label}}</div> </div>
理想情况下,你应该避免这样做。
但是,如果真的需要,那么可以注入并使用$compile
服务,然后使用element.append
。
如果你的指令不需要访问特定的作用域,那么你甚至可以把$compile
和$rootScope
服务分配给应用程序模块的run
函数的window
,然后通过创build一个新的scope
$rootScope.new()
)并使用$rootScope.apply()
来包装元素的追加。
如果可以的话,你真的想避免做任何jquery,但是不久之前我遇到了类似的问题,这里是我的问题和正确的答案,应该能够帮助你。 简短的答案是使用$ compile。
接受的答案没有提供一个完整的例子,这里是一个:
https://codepen.io/rhinojosahdz/pen/ZpGLZG
<body ng-app="app" ng-controller="Ctrl1 as ctrl1"> </body> <script> angular.module('app',[]) .controller('Ctrl1', ['$scope', '$compile', function($scope, $compile){ var vm = this; vm.x = 123; $('body').append($compile("<hola x='ctrl1.x' />")($scope)); }]) .directive('hola', function(){ return { template: '<div ng-click="vm.alertXFromGivenScope()">click me!</div>' ,scope: { x : '=' } ,controller: function(){ var vm = this; vm.alertXFromGivenScope = function(){ alert(vm.x); }; } ,controllerAs: 'vm' ,bindToController: true } }) <script>
尝试这个
angular.element($("#appendToDiv")).append($compile("<my-angular-directive />")($scope));