2015-07-04 1 views
19

ho la seguente direttiva:Angularjs: Come passare la funzione in fase di compilazione

app.directive('pagedownAdmin', ['$compile', '$timeout', function ($compile, $timeout) { 
    var nextId = 0; 
    var converter = Markdown.getSanitizingConverter(); 
    converter.hooks.chain("preBlockGamut", function (text, rbg) { 
     return text.replace(/^ {0,3}""" *\n((?:.*?\n)+?) {0,3}""" *$/gm, function (whole, inner) { 
      return "<blockquote>" + rbg(inner) + "</blockquote>\n"; 
     }); 
    }); 

    return { 
     restrict: "E", 
     scope: { 
      content: "=", 
      modal: '=modal' 
     }, 
     template: '<div class="pagedown-bootstrap-editor"></div>', 
     link: function (scope, iElement, attrs) { 

      var editorUniqueId; 

      if (attrs.id == null) { 
       editorUniqueId = nextId++; 
      } else { 
       editorUniqueId = attrs.id; 
      } 

      scope.hideDiv = function() { 
       document.getElementById("wmd-button-bar-" + editorUniqueId).style.display = 'none'; 
      }; 

      scope.showDiv = function() { 
       document.getElementById("wmd-button-bar-" + editorUniqueId).style.display = 'block'; 
      }; 

      scope; 

      var newElement = $compile(
       '<div>' + 
        '<div class="wmd-panel">' + 
         '<div data-ng-hide="modal.wmdPreview == true" id="wmd-button-bar-' + editorUniqueId + '" style="display:none;"></div>' + 
          '<textarea on-focus="showDiv()" on-blur="hideDiv()" data-ng-hide="modal.wmdPreview == true" class="wmd-input" id="wmd-input-' + editorUniqueId + '" ng-model="content" >' + 
          '</textarea>' + 
         '</div>' + 
        '<div data-ng-show="modal.wmdPreview == true" id="wmd-preview-' + editorUniqueId + '" class="pagedownPreview wmd-panel wmd-preview">test div</div>' + 
       '</div>')(scope) 
      ; 

      iElement.append(newElement); 

      var help = angular.isFunction(scope.help) ? scope.help : function() { 
       // redirect to the guide by default 
       $window.open("http://daringfireball.net/projects/markdown/syntax", "_blank"); 
      }; 

      var editor = new Markdown.Editor(converter, "-" + editorUniqueId, { 
       handler: help 
      }); 

      var editorElement = angular.element(document.getElementById("wmd-input-" + editorUniqueId)); 

      editor.hooks.chain("onPreviewRefresh", function() { 
       // wire up changes caused by user interaction with the pagedown controls 
       // and do within $apply 
       $timeout(function() { 
        scope.content = editorElement.val(); 
       }); 
      }); 

      editor.run(); 
     } 
    } 
}]); 

Dentro ho la funzione showDiv e hideDiv che mostrare e nascondere il menu dell'editor pagina quando fai clic dentro e fuori del textarea .

sto passando le funzioni ad un evento all'interno della compilazione:

//First try 
<textarea onfocus="showDiv()" onblur="hideDiv()"></textarea> 

quando clicco all'interno e all'esterno del textarea ricevo gli errori:

Uncaught ReferenceError: on is not defined 
Uncaught ReferenceError: off is not defined 

//Second try 
<textarea on-focus="showDiv()" on-blur="hideDiv()"></textarea> 

quando clicco dentro e fuori textarea non sta succedendo nulla. Nessun errore ma non chiamare la funzione neanche.

Qualcuno può indicarmi la giusta direzione? Grazie

+4

Utilizzare 'ng-focus' e' ng-blur' invece di 'onfocus' e' onblur' rispettivamente – Samir

+0

Non utilizzare 'new'as nome variabile, è uno speciale che non è possibile utilizzare come var –

+0

@ Michelem il nome var 'nuovo' è solo a scopo di questa domanda :) –

risposta

2

Grazie ragazzi per cercare di aiutare. Ho trovato cosa c'era di sbagliato nel mio codice. Ho fatto un errore molto stupido/noob. Ho utilizzato on-focus anziché ng-focus e on-blur anziché ng-blur.

+4

Puoi aggiungere questo come una modifica alla tua domanda e se @Rouby ha risposto al tuo punto interrogativo come risposta. –

12

Invece di utilizzare lo stesso ambito, creare un'istanza di un nuovo ambito (scope.$new()) e assegnare le funzioni a questo nuovo ambito. Perché altrimenti si sovrascriveranno i riferimenti funzione assegnati dalla dichiarazione dell'ambito all'oggetto scope.

var newScope = scope.$new(); 
newScope.hideDiv = function() {...}; 
newScope.showDiv = function() {...}; 
... 
var newElement = $compile(...)(newScope); 

E per utilizzare la funzione di riferimenti riportati al campo di applicazione originale (della direttiva) è possibile chiamare quelli nelle funzioni di nuova Ambito di applicazione (ad esempio function() { scope.hideDiv(); }).

plnkr di lavoro:

http://plnkr.co/edit/nGux3DOsrcPBcmz43p2A?p=preview

https://docs.angularjs.org/api/ng/service/$compile https://code.angularjs.org/1.3.16/docs/api/ng/type/$rootScope.Scope#$new