2015-05-12 1 views
3

Я использую ng-repeat, и мне нужно передать переменную области видимости в функцию компиляции директивы. Я знаю, как это сделать со ссылкой, но не с функцией компиляции.Я могу передать переменную области видимости в функцию ссылки директивы, но не функцию компиляции, угловую

Мой HTML выглядит следующим образом:

<div ng-repeat="item in chapter.main"> 
     <block type="item.type"></block> 
    </div> 

Скажем item.type = "бла" независимо от пункта. Тогда эта функция отлично работает ссылка

app.directive('block', function() { 
    return { 
     restrict: 'E', 
     link: function(scope, element, attributes){ 
      scope.$watch(attributes.type, function(value){ 
       console.log(value); //will output "blah" which is correct 
      }); 

     } 
    } 
}); 

Но я не могу сделать то же самое с компиляцией?

app.directive('block', function() { 
    return { 
     restrict: 'E', 
     compile: function(element, attrs, scope) { 
     scope.$watch(attrs.type, function(value){ 
      console.log(value); 
     }); 
     } 
    } 
}); 

Я получаю ошибку "не может прочитать свойство $ часов неопределенного" ..

Это, как я хотел бы свою директиву выглядеть следующим образом:

app.directive('block', function() { 
    return { 
     restrict: 'E', 
     compile: function(element, attrs) { 
     element.append('<div ng-include="\'{{type}}-template.html\'"></div>'); 
     //or element.append('<div ng-include="\'{' + attrs.type + '}-template.html\'"></div>'); 
     //except the above won't interpret attr.type as a variable, just as the literal string 'item.type' 
     } 
    } 
}); 
+0

Вот интересный [статья] (http://www.jvandemo.com/the-nitty- gritty-of-compile-and-link-functions-inside-angularjs-директивы /) о 'компиляции' и о том, как это работает в' Angularjs'. – themyth92

ответ

2

The compile функция не имеет scope как один из его параметров.

function compile(tElement, tAttrs, transclude) { ... }

Примечание: transclude осуждается в последней версии Угловое.

Есть ли причина, по которой вы не хотите использовать link?

Из DOC

компиляция функция связана с преобразуя шаблон DOM. Поскольку большинство директив не выполняет трансформацию шаблона, оно часто не используется. Функция компиляции принимает следующие аргументы:

tElement - элемент шаблона - элемент, в котором объявлена ​​директива. Безопасно делать трансформацию шаблона только для элемента и дочерних элементов.

tAttrs - атрибуты шаблона - нормализованный список атрибутов, объявленных в этом элементе, разделяемых между всеми функциями компиляции директивы.

transclude - это transclude функции связывания [устаревшее]: функция (сфера, cloneLinkingFn)

UPDATE

Чтобы получить доступ к сферам внутри compile функции, вам нужно иметь либо preLink или postLink функция. В вашем случае вам нужна только функция postLink. Так что это ...

compile: function compile(tElement, tAttrs, transclude) { 
    return function postLink(scope, element, attrs) { ... } 
}, 

Предложенное решение Может не быть точным, но должно помочь вам на вашем пути.

HTML

<div ng-app="myApp" ng-controller="app"> 
    <block type="item.type"></block> 
</div> 

JS (контроллер + директива)

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

myApp.controller('app', function ($scope, $http) { 
    $scope.item = { 
     type: 'someTmpl' 
    }; 
}).directive('block', ['$compile', function ($compile) { 
    return { 
     restrict: 'AE', 
     transclude: true, 
     scope: { 
      type: '=' 
     }, 
     compile: function (element, attrs) { 
      return function (scope, element, attrs) { 
       var tmpl; 
       tmpl = scope.type + '-template.html'; 

       console.log(tmpl); 

       element.append('<div ng-include=' + tmpl + '></div>'); 

       $compile(element.contents())(scope); 
      }; 
     } 
    }; 
}]); 
+0

Хм, я просто не знаю, как использовать ссылку - вы имеете в виду что-то вроде добавления элемента element.append ('

'); 'внутри функции link/watch? Потому что я пробовал это и ничего не получил ... – thatandrey

+0

@thatandrey, проверьте предлагаемое решение выше;) – dcodesmith

+0

Привет, спасибо, я думаю, что это должно быть 'console.log (tmpl)'? И я закончил использование 'element.append ('

');' потому что я думаю, что должен быть дополнительный набор круглых скобок вокруг имени файла, иначе шаблон не был загружен, иначе он отлично работает, спасибо! – thatandrey

Смежные вопросы