2

Я хочу добавить другой экземпляр моей директивы в родительскую директиву, но я не могу использовать $ apply для перекомпиляции моей директивы.Добавление директивы внутри директивы программно

Я думаю, что я пропустил что-то где-то здесь :)

Мой HTML код

<div ng-app="TestApp"> 
    <div ng-controller="TestCtrl"> 
     <input ng-model="NewData" /> 
     <button ng-click="AddNewData($event)">Add New</button> 
     <br /><br /> 
     <div test-collector="testColScope" id="testCol"> 
      <div test-data="" xx-value="Mouse" xx-href="https://fb.com"></div> 
      <div test-data="" xx-value="Keyboard" xx-href="https://goo.gl"></div> 
     </div>   
    </div> 
</div> 

Мой JavaScript код

var app = angular.module('TestApp', []); 

app.controller('TestCtrl', ['$scope', function($scope){ 

    $scope.AddNewData = function($event){ 

     // i also want to access this but it shows undefined 
     console.log("test-collector", $scope.testColScope); 

     var div = $('<div></div>') 
     .attr(
      { 
       "test-data":"", 
       "xx-value":$scope.NewData, 
       "xx-href":"http://p.com" 
      });  

     //$scope.$apply(function(){ 
      $('#testCol').append(div); 
     //});   
    }; 
}]); 

app.directive("testCollector", function() { 
    return { 
     restrict: "A", 
     scope: { 

     }, 
     transclude: true, 
     replace: true, 
     controller: function($scope) { 
      console.log($scope); 
     }, 
     link: function(scope, element, attrs) { 
      console.log(attrs); 
      scope[attrs.testCollector] = { 
       Enteng : 'Dagpin' 
      }; 
     }, 
     template: '<div>' + 
         '<ul><div ng-transclude></div></ul>' + 
        '</div>' 
    } 
}); 

app.directive("testData", function(){ 
    return { 
     restrict: "A", 
     require: '^testCollector', 
     transclude: true, 
     replace: true, 
     scope: { 
      xxValue: '@', 
      xxHref: "@" 
     }, 
     template: '<li><a href="{{xxHref}}">{{xxValue}}</a></li>' 
    } 
}); 

Вот Fiddle with Problem

+0

Вы не можете получить доступ к значениям testCollector из TestCtrl, потому что сборщик проб определяет новую область. Значения по областям не распространяются. – Enzey

+0

есть ли способ сказать, как область. $ Parent [attrs.testCollector] = { Enteng: 'Dagpin' }; ? –

+1

Вы могли бы, но это сработало бы, если бы вы удалили дочернюю область в директиве. Просто не определяйте 'scope: {}' в директиве testCollector. – Enzey

ответ

1

Чтобы понять, что вставлен угловой новый элемент, вам нужно сначала скомпилировать этот элемент, используя $compile сервис, например $compile(div)($scope), и только вы можете добавить этот элемент в Angular DOM.

И вы уже указали директиву на html, поэтому структура div изменяется.

вместо делать $ ('# testCol') использовать angular.element('#testCol ul div')

Вот Working Fiddle

Update 1

Согласно @enzey манипуляции DOM не должно быть сделано внутри контроллера. Это должно быть сделано внутри директивы. Вот почему @Vincent & Я внес изменения в скрипку. Логика манипуляции DOM была перенесена в внутреннюю директиву.

Вот Updated Fiddle

+0

Выполнение манипуляций с DOM с контроллером - это угловая плохая практика. Это старый способ JavaScript, который совершенно не нужен при использовании Angular, поскольку он предназначен. – Enzey

+0

@Enzey, что вы хотите сказать для одиночного, ng-click только мне нужно создать директиву? Я использую angular.element, который безопасен –

+0

Вы должны сначала добавить ng-click как часть HTML. Если нет, и вы добавляете его программно, то да, вы бы использовали директиву. – Enzey

0

Вы пытаетесь манипулировать DOM внутри контроллера. Изменение DOM является целью директив. Это первое, что вам нужно решить.

Что касается добавления директивы дочернему элементу в DOM, вам просто нужно использовать функцию компиляции директивы.

Module.directive('name', function() { 
    return { 
     compile: function ($element, $attrs) { 
      \\ here 
     } 
    } 
} 
Смежные вопросы