如何通过jQuery的.append()添加DOM元素(Angular指令)?

时间:2013-11-18 22:24:34

标签: jquery angularjs

有没有办法用jQuery方法添加一个Angular指令元素,如append(),并让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不会启动并发挥它的魔力。

6 个答案:

答案 0 :(得分:76)

正确的方法是使用:$compile并且如果您的指令返回:directive definition object(这是btw。推荐的方式),您可以调用link函数在它上面(例如注入scope)。

$('body').append($compile("<my-angular-directive />")(scope));
scope.$apply(); 

答案 1 :(得分:17)

完整示例,来自the Angular documentation

&#13;
&#13;
// 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);
&#13;
<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>
&#13;
&#13;
&#13;

答案 2 :(得分:2)

理想情况下,你应该避免这样做。

但是,如果真的,真的,真的需要,那么您可以注入并使用$compile service后跟element.append

如果您的指令不需要访问特定范围,那么您甚至可以将$compile$rootScope服务分配给window { {1}}应用程序模块的功能,然后通过创建新的runscope)从角度上下文之外使用它们,并使用$rootScope.new()包装元素的附加。

答案 3 :(得分:2)

接受的答案并没有提供一个完整的例子,这里有一个:

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>

答案 4 :(得分:1)

如果可以的话,你真的想避免做任何jquery,但是我不久前遇到了类似的问题,这里是my question并且应该能够帮助你的正确答案。简短的回答是使用$ compile。

答案 5 :(得分:0)

试试这个

angular.element($("#appendToDiv")).append($compile("<my-angular-directive />")($scope));