2014-11-06 21 views
15

Tôi có chỉ thị cha mẹ nơi tôi muốn tự động thêm chỉ thị con trong hàm liên kết. Chỉ thị trẻ em^yêu cầu phụ huynh. Tôi có thể thêm bất kỳ phần tử html nào nhưng ngay sau khi tôi cố gắng $ biên dịch chỉ thị con tôi nhận được lỗi sau mà không thể tìm thấy bộ điều khiển bắt buộc. Nếu tôi tự thêm các chỉ thị con thì nó hoạt động hoàn hảo.Chỉ thị trẻ em trong chỉ thị cha mẹ

Lỗi:

Error: [$compile:ctreq] Controller 'myInput', required by directive 'myKey', can't be found! 

mẫu của tôi sẽ giống như thế này sau khi thêm các yếu tố:

<myInput> 
<myKey></myKey> <-- added dynamically 
<myKey></myKey> <-- added dynamically 
<myKey></myKey> <-- added dynamically 
    .... 
</myInput> 

myInput chỉ:

angular.module('myModule').directive('myInput', ['$log', '$templateCache', '$compile', function($log, $templateCache, $compile) { 
    return { 
    restrict: 'E', 
    transclude: true, 
    scope: { 
     service: '=',   // expects a stimulus object provided by the tatoolStimulusService 
     onkeydown: '&'   // method called on key press 
    }, 
    controller: ['$scope', function($scope) { 
     this.addKey = function(keyCode, value) { 
     $scope.service.addInputKey(keyCode, { givenResponse: value }); 
     }; 
    }], 
    link: function (scope, element, attr) { 

     // add keys directives 
     angular.forEach(scope.service.registeredKeyInputs, function(value, key) { 
     var keyEl = angular.element(
      $compile('<myKey code="'+ key +'" response="'+ value.response +'"></myKey >')($rootScope)); 
     element.children(":first").append(keyEl); 
     }); 

    }, 
    template: '<div ng-transclude></div>' 
    }; 
}]); 

chỉ MyKey:

angular.module('myModule').directive('myKey', ['$log', '$sce', function($log, $sce) { 
    return { 
    restrict: 'E', 
    scope: {}, 
    require: '^myInput', 
    link: function (scope, element, attr, myCtrl) { 
     myCtrl.addKey(attr.code, attr.response); 

     // ... 
    }, 
    template: '<div class="key"><span ng-bind-html="key"></span></div>' 
    }; 
}]); 

Trả lời

22

Thay đổi thứ tự của biên dịch thêm hoạt động để append-biên dịch:

var keyEl = angular.element('<myKey code="'+ key +'" response="'+ value.response +'"></myKey>'); 
element.append(keyEl); 
$compile(keyEl)(scope); 

Rõ ràng điều quan trọng trong trường hợp này (định vị thị yếu tố phụ huynh) là, mà yếu tố mới đang được biên soạn là đã trong DOM.

Trừ khi phần tử DOM được thêm vào DOM, không có phần tử gốc (thuộc tính parentNodenull). Khi Angular tìm kiếm ^myInput, nó di chuyển lên cây DOM cho đến khi tìm thấy nút có chỉ thị bắt buộc. Nếu phần tử chưa có trong DOM, tìm kiếm này không thành công ngay lập tức, bởi vì phần tử không có một đơn parentNode. Do đó lỗi bạn đang nhận được.

Ngoài ra tôi khuyên bạn nên thay đổi tên của các chỉ thị của bạn từ camelCase để rắn hợp cụ thể:

<my-input> 
    <my-key></my-key> 
</my-input> 

Sau đó biên dịch một phần cũng sẽ thay đổi:

angular.element('<my-key code="'+ key +'" response="'+ value.response +'"></my-key >'); 
+0

đó làm việc một cách hoàn hảo và thậm chí có ý nghĩa (mặc dù tài liệu này sẽ giúp ích). Tôi đã chỉ sử dụng tên giả trong bài viết nhưng bạn phải tất nhiên với trường hợp con rắn. Cảm ơn một lần nữa. – jimmy

+1

Tôi không biết về tài liệu, nhưng thật dễ hiểu. Cho đến khi phần tử DOM được nối vào cây DOM nó ** không ** có một parent (thuộc tính 'parentNode' của nó là' null'). Khi Angular tìm kiếm '^ myInput', nó di chuyển lên cây DOM cho đến khi nó tìm thấy một nút có chỉ thị bắt buộc. Trong trường hợp của chúng tôi nó không thành công ngay lập tức, bởi vì phần tử không có một parentNode đơn. – dfsq

Các vấn đề liên quan