Câu hỏi Làm thế nào để thêm DOM Elements (Chỉ thị góc) thông qua jQuery .append ()?


Có cách nào để thêm một phần tử là một chỉ thị Góc với các phương thức jQuery như append() và có Angular làm biên dịch / liên kết của nó để làm cho nó hoạt động như thể bạn đã đưa chỉ thị vào vị trí đầu tiên?

Thí dụ:

app.directive('myAngularDirective', [function () {
    ...
    // Lots of stuff in here; works when used normally but not when added via jQuery
});

$("body").append("<my-angular-directive />");

Nó hiện chỉ gắn thêm một phần tử DOM rỗng gọi là "my-angular-directive", nhưng Angular không đá vào và làm phép thuật của nó.


47
2017-11-18 22:24


gốc


Nghi ngờ của tôi là bạn sẽ cần phải nói với Angular rằng phần tử mới bây giờ tồn tại, vì nó có thể không tồn tại trên doc Ready nếu bạn thêm nó một cách năng động - hammus


Các câu trả lời:


Cách đi đúng là sử dụng: $ compile và trong trường hợp chỉ thị của bạn trả về: directive definition object (đó là btw. cách được khuyên dùng), bạn có thể gọi link chức năng trên nó (để tiêm scope, ví dụ).

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

70
2017-11-18 22:37



mã của bạn chưa hoàn thành. u có thể xin vui lòng gửi một phiên bản jsfiddle mã của bạn. - Monojit Sarkar
Nếu bạn đã ở trong một $digest chu kỳ? Có lẽ sử dụng $timeout thay thế. - Ivan Rubinson


Một ví dụ hoàn chỉnh, từ tài liệu hướng dẫn góc:

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


16
2017-08-06 01:01





Lý tưởng nhất là bạn nên tránh làm điều đó.

Tuy nhiên, nếu bạn Thực sự thực sự thực sự cần, sau đó bạn có thể tiêm và sử dụng $compile dịch vụ theo sau bởi một element.append.

Nếu là của bạn chỉ thị không cần quyền truy cập vào một phạm vi cụ thể, sau đó bạn thậm chí có thể chỉ định $compile và $rootScope dịch vụ cho window bên trong run chức năng của mô-đun ứng dụng của bạn và sau đó sử dụng chúng từ bên ngoài ngữ cảnh góc bằng cách tạo một mô-đun mới scope ($rootScope.new()) và bọc thêm phần tử bằng cách sử dụng $rootScope.apply().


2
2017-11-18 22:38



Tại sao nên bổ sung các yếu tố thực tế tránh được? Có cách nào khác không? - marcospgp
Tôi đoán bạn sẽ có chỉ thị đó trong một chế độ xem và sử dụng một cái gì đó như ui.router để đặt chế độ xem trong chế độ xem ui - Neil


Bạn thực sự muốn tránh làm bất kỳ jquery nếu bạn có thể, nhưng tôi chạy vào một vấn đề tương tự cách đây không lâu, đây là câu hỏi của tôi và câu trả lời đúng sẽ có thể giúp bạn. Câu trả lời ngắn gọn là sử dụng $ compile.


1
2017-11-18 22:39





Câu trả lời được chấp nhận không cung cấp một ví dụ hoàn chỉnh, đây là một ví dụ:

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>

1
2017-09-07 15:35



Thao tác DOM không nên được thực hiện trong bộ điều khiển. - bhantol


Thử cái này

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

0
2018-04-27 10:19