2013-03-24 4 views
3

Update: Fiddle ж/полное решение: http://jsfiddle.net/langdonx/VXBHG/Создание директивы AngularJS для кнопки JQuery UI


В рамках усилий, чтобы сравнить и контрастных KnockoutJS и AngularJS, я побежал через KnockoutJS interactive tutorial, и после каждого раздела, Я переписал его в AngularJS, используя то, что я уже знал + AngularJS reference.

Когда я добрался до шага 3 учебника Creating custom bindings, я подумал, что было бы подходящее время, чтобы развернуть на Angular Directives и написать собственный тег. Затем я потерпел неудачу.

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

  • (fiddle): Я понял мой вопрос рамочный, но это возможно только PASSTHROUGH ng-click? Единственный способ заставить его работать - переименовать его в jqb-click, что немного раздражает.
  • (fiddle): Как только я применил .button() к моему элементу, все пошло странно. Моя догадка заключается в том, что и Angular, и jQuery UI управляют HTML. Я бы этого не ожидал, но Angular, кажется, предоставляет свой собственный span для моего button (см. Строку 21 JavaScript), и, конечно же, пользовательский интерфейс jQuery, которого я ожидал бы. Я взломал HTML, чтобы он выглядел правильно, но даже до этого ни одна из функций не работает. У меня все еще есть проблема с областью, и привязка шаблона отсутствует. Что мне не хватает?

Я понимаю, что есть проект AngularUI, на который я должен обратить внимание, и я могу, возможно, снять то, что я пытаюсь сделать с помощью только CSS, но на данный момент это больше связано с тем, как лучше использовать директивы чем думать, что это хорошая идея.

ответ

6

Вы можете создать изолированную область действия в директиве, установив параметр scope или разрешить использовать родительскую область, не устанавливая ее.

Поскольку вы хотите ng-click от родительской области, вероятно самый простой для этого экземпляра, чтобы использовать родительский сферу в пределах директивы:

Один трюк заключается в использовании $timeout в директиве перед тем maniplulatig в DOM в шаблонных директивы, чтобы дать DOM время перерисовки перед манипуляцией, иначе кажется, что элементы не существуют во времени.

Я использовал атрибут, чтобы передать текст, а не беспокоиться о компиляции заговора. Таким образом, выражение будет уже скомпилировано при добавлении шаблона, а обратный вызов link обеспечивает легкий доступ к атрибутам.

<jqbutton ng-click="test(3)" text="{{title}} 3"></jqbutton> 
angular.module('Components', []) 
    .directive('jqbutton', function ($timeout) { 
    return { 
     restrict: 'E', // says that this directive is only for html elements 
     replace: true,   
     template: '<button></button>', 
     link: function (scope, element, attrs) { 
      // turn the button into a jQuery button 
      $timeout(function() { 
       /* set text from attribute of custom tag*/ 
       element.text(attrs.text).button(); 
     }, 10);/* very slight delay, even using "0" works*/ 
     } 
    }; 
}); 

Демо: http://jsfiddle.net/gWjXc/8/

Директивы являются очень мощными, но и иметь немного кривой обучения.Кроме того, по сравнению с угловым нокаутировать, угловой больше из меты структуры, которая в конечном счете имеет гораздо больше гибкости человека, чем Нокаут

Очень полезно читать для понимания сферы в директивах:

https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-Prototypal-Inheritance

+0

ARGH, так отсутствие директивного контроллера и 'ng-transclude', давайте расширим область действия' ng-click', как правило ... сложно. – Langdon

+1

Контроллер no..directive также может также использовать область родительского контроллера. Все зависит от того, установлен ли параметр scope. 'ng-transclude' также не влияет на сферу применения. 'transclude' по существу предназначен для определения того, следует ли переносить существующий html в тег в новый шаблон или отказаться от него. – charlietfl

+0

О, я думаю, это был тот факт, что мой контроллер определил функцию с именем test, а затем, когда я удалил это, было фактом, что я имеет 'scope: {}', который, как говорят документы, создает изолированную область. Это то, что я получаю для копирования из примеров. :) Спасибо за вашу помощь. Теперь, когда есть текстовый атрибут, я смог заставить 'attrs. $ Наблюдать' работать. Ура! – Langdon