How to add DOM Elements (Angular directives) via jQuery's .append()?

前端 未结 6 1821
半阙折子戏
半阙折子戏 2020-12-13 23:40

Is there any way to add an element that is an Angular directive with jQuery methods like append() and have Angular do its compilation/linking to make it work as

相关标签:
6条回答
  • 2020-12-13 23:50

    Ideally you should avoid doing that.

    However, if you really, really, really need to, then you can inject and use the $compile service followed by an element.append.

    If your directive doesn't need access to a specific scope, then you can even assign the $compile and $rootScope service to window in the run function of your application's module and then use them from outside the angular context by creating a new scope ($rootScope.new()) and wrap the appending of element by using $rootScope.apply().

    0 讨论(0)
  • 2020-12-13 23:52

    The accepted answer didn't provide a complete example, here's one:

    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>
    
    0 讨论(0)
  • 2020-12-13 23:57

    You really want to avoid doing any jquery if you can, but I ran into a similar problem not too long ago, here was my question and the correct answer that should be able to help you out. The short answer is using $compile.

    0 讨论(0)
  • 2020-12-14 00:00

    A complete example, from the Angular documentation:

    // 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>

    0 讨论(0)
  • 2020-12-14 00:00

    Try this

    angular.element($("#appendToDiv")).append($compile("<my-angular-directive />")($scope));
    
    0 讨论(0)
  • 2020-12-14 00:16

    The right way to go is to use: $compile and in case your directive returns: directive definition object (which is btw. the recommended way to go) you can then call link function on it (to inject scope, for example).

    $('body').append($compile("<my-angular-directive />")(scope));
    scope.$apply(); 
    
    0 讨论(0)
提交回复
热议问题