2017-03-27 2 views
0

Ich habe eine Direktive, die für die Funktionalität eines Bestätigungsprozesses verantwortlich ist (siehe Bilder). Es funktioniert wie erwartet, außer nach dem Klicken auf die Schaltfläche Absenden, wird das Häkchen-Symbol für alle tr angezeigt. Es sollte jedoch nur auf dem tr angezeigt werden, der bestätigt wurde.AngularJS-Direktive (Problem mit der Isolierung des Scope)

Leider konnte ich keinen funktionierenden Plunker erstellen und hoffe, dass die Bilder für Sie ausreichen, um mein Problem zu verstehen.

Was mache ich falsch?

Angular-Richtlinie:

.directive('confirm', function($timeout) { 
     return { 
     restrict: 'A', 
     scope: true, // isolate the scope to trigger target individually 
     link: function(scope, element) { 
      $timeout(function() { 
      var barIcon = angular.element(element[0].querySelector('.config-menu-bars')); 
      var banIcon = angular.element(element[0].querySelector('.config-menu-ban')); 
      var checkIcon = angular.element(element[0].querySelector('.config-menu-checked')); 
      var confirmLink = angular.element(element[0].querySelector('.confirm')); 
      var textArea = angular.element(element[0].querySelector('.confirmation-note')); 

      // These elements are outside the scope of the directive 
      var confirmBox = angular.element('.accept-terminplanung'); 
      var submitButton = angular.element('.submit-appointment'); 
      var confirmCheckbox = angular.element('.appointment'); 

      // Hide barIcon and show banIcon, textArea and confirmBox 
      confirmLink.bind('click', function() { 
       barIcon.hide(); 
       banIcon.show(); 
       textArea.show(); 
       confirmBox.show(); 
      }); 

      // Hide banIcon, textArea, confirmBox and show barIcon 
      banIcon.bind('click', function() { 
       banIcon.hide(); 
       textArea.hide(); 
       confirmBox.hide(); 
       barIcon.show(); 
       confirmCheckbox.parent().removeClass('checked'); 
       submitButton.addClass("disabled"); 
      }); 

      // Hide barIcon, textArea, confirmBox and show checkIcon after clicking the submitButton 
      submitButton.bind('click', function() { 
       banIcon.hide(); 
       textArea.hide(); 
       confirmBox.hide(); 
       checkIcon.show(); 
       confirmCheckbox.parent().removeClass('checked'); 
       submitButton.addClass("disabled"); 
      }); 

      // checkbox functionality whithin the confirmBox 
      confirmCheckbox.on('ifChecked', function() { 
       submitButton.removeClass('disabled'); 
      }); 

      confirmCheckbox.on('ifUnchecked', function() { 
       submitButton.addClass('disabled'); 
      }); 

      }); 
     } 
     } 
    }); 

HTML:

 <table class="table table-hover"> 
      <thead> 
      <tr> 
       <th>Ausbildung</th> 
       <th>Termine</th> 
       <th>Ausbildungsstätte</th> 
      </tr> 
      </thead> 
      <tbody> 
      <tr confirm> 
       <td> 
       <ul class="nav navbar-nav"> 
        <li class="dropdown"> 
        <a aria-expanded="false" role="button" data-target="#" class="dropdown-toggle config-menu config-menu-bars" data-toggle="dropdown"> 
         <i class="fa fa-bars"></i> 
        </a> 
        <a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-ban" style="display: none;"> 
         <i class="fa fa-ban"></i> 
        </a> 
        <a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-checked" style="display: none;"> 
         <i class="fa fa-check-square-o"></i> 
        </a> 
        <ul role="menu" class="dropdown-menu"> 
         <li><a class="confirm" data-target="">Bestätigen</a></li> 
         <li><a class="move" data-target="">Verschieben</a></li> 
        </ul> 
        </li> 
       </ul> 
       </td> 
       <td> 
       <p><strong>Ausbildungsname</strong></p> 
       <p>Kürzel</p> 
       </td> 
       <td> 
       <p><strong class="text-navy">28.05.2016 </strong>| 09:00 - 16:00 Uhr</p> 
       <p><strong class="text-navy">29.05.2016 </strong>| 09:00 - 16:00 Uhr</p> 
       <p><strong class="text-navy">30.05.2016 </strong>| 09:00 - 16:00 Uhr</p> 
       </td> 
       <td> 
       <p><strong>Ausbildungsstätte Wunderfull ABC</strong></p> 
       <p>Musterstraße 1, 1234 Musterstadt</p> 
       <p><i class="fa fa-th-large"></i></span> Seminarraum, Kursraum, Fitnessfläche</p> 
       </td> 
      </tr> 
      <tr confirm> 
       <td> 
       <ul class="nav navbar-nav"> 
        <li class="dropdown"> 
        <a aria-expanded="false" role="button" data-target="#" class="dropdown-toggle config-menu config-menu-bars" data-toggle="dropdown"> 
         <i class="fa fa-bars"></i> 
        </a> 
        <a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-ban" style="display: none;"> 
         <i class="fa fa-ban"></i> 
        </a> 
        <a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-checked" style="display: none;"> 
         <i class="fa fa-check-square-o"></i> 
        </a> 
        <ul role="menu" class="dropdown-menu"> 
         <li><a class="confirm" data-target="">Bestätigen</a></li> 
         <li><a class="move" data-target="">Verschieben</a></li> 
        </ul> 
        </li> 
       </ul> 
       </td> 
       <td> 
       <p><strong>Ausbildungsname</strong></p> 
       <p>Kürzel</p> 
       </td> 
       <td> 
       <p><strong class="text-navy">28.05.2016 </strong>| 09:00 - 16:00 Uhr</p> 
       <p><strong class="text-navy">29.05.2016 </strong>| 09:00 - 16:00 Uhr</p> 
       </td> 
       <td> 
       <p><strong>Ausbildungsstätte Wunderfull ABC</strong></p> 
       <p>Musterstraße 1, 1234 Musterstadt</p> 
       <p><i class="fa fa-th-large"></i></span> Seminarraum, Kursraum, Fitnessfläche</p> 
       </td> 
      </tr> 
      <tr confirm> 
       <td> 
       <ul class="nav navbar-nav"> 
        <li class="dropdown"> 
        <a aria-expanded="false" role="button" data-target="#" class="dropdown-toggle config-menu config-menu-bars" data-toggle="dropdown"> 
         <i class="fa fa-bars"></i> 
        </a> 
        <a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-ban" style="display: none;"> 
         <i class="fa fa-ban"></i> 
        </a> 
        <a aria-expanded="false" role="button" class="dropdown-toggle config-menu config-menu-checked" style="display: none;"> 
         <i class="fa fa-check-square-o"></i> 
        </a> 
        <ul role="menu" class="dropdown-menu"> 
         <li><a class="confirm" data-target="">Bestätigen</a></li> 
         <li><a class="move" data-target="">Verschieben</a></li> 
        </ul> 
        </li> 
       </ul> 
       </td> 
       <td> 
       <p><strong>Ausbildungsname</strong></p> 
       <p>Kürzel</p> 
       </td> 
       <td> 
       <p><strong class="text-navy">28.05.2016 </strong>| 09:00 - 16:00 Uhr</p> 
       </td> 
       <td> 
       <p><strong>Ausbildungsstätte Wunderfull ABC</strong></p> 
       <p>Musterstraße 1, 1234 Musterstadt</p> 
       <p><i class="fa fa-th-large"></i></span> Seminarraum, Kursraum, Fitnessfläche</p> 
       </td> 
      </tr> 
      </tbody> 
     </table> 
     </div> 
     <div class="panel panel-default confirm-panel accept-terminplanung" confirm> 
     <div class="panel-body text-muted ibox-heading"> 
      <form action="#" method="post" role="form"> 
      <div class="i-checks" ichecks> 
       <label class=""> 
       <div class="icheckbox_square-green"> 
        <input type="checkbox" class="i-checks appointment"> 
       </div> 
       <p class="no-margins">Hiermit akzeptiere ich die Bedingungen des geschlossenen Dozentenvertrages und nehme den Bildungsauftrag für die ausgewählten Ausbildungen verbindlich an.</p> 
       </label> 
      </div> 
      <button type="button" name="termin-bestaetigen" class="btn btn-sm btn-w-m btn-warning submit-appointment disabled">Terminplanung übernehmen</button> 
      </form> 
     </div> 
     </div> 

Bilder:

1) enter image description here

2) enter image description here

3) enter image description here

4) enter image description here

5) enter image description here

Antwort

1

Du bist Verwendung scope: true in Ihrer Richtlinie. Dadurch wird ein neuer untergeordneter Bereich erstellt, der vom übergeordneten Bereich erbt. Dies ist nicht derselbe Bereich wie ein isolierter Bereich. Wenn Sie mehrere Direktiven auf derselben übergeordneten Ebene haben (in Ihrem Fall confirm), verwenden alle denselben Direktivenbereich.

Um es klar zu machen: scope: true verwendet, wird ein neues Kind Umfang machen, es sei denn, man bereits existiert (durch eine andere Richtlinie zum Beispiel erstellt). In Ihrem Fall verwenden alle Bestätigungsdirektiven denselben Bereich.

Was sollten Sie tun, um einen Isolat-Bereich zu erstellen?

scope: {...} geben Sie einen Objekt-Hash. Dadurch wird ein vollständig isolierter Bereich erstellt, der es ermöglicht, dass eine Anweisung auf derselben Bereichsebene wiederverwendet wird, ohne dass sie sich gegenseitig stören.

Sie können viel mehr Informationen über diese finden Sie hier: Angular JS Docs - Scope

Der Umfang Eigenschaft falsch sein kann, wahr, oder ein Objekt:

false (Standard): Kein Spielraum für erstellt werden die Richtlinie. Die Richtlinie wird den Bereich ihrer Eltern verwenden.

true: Ein neuer untergeordneter Bereich, der prototypisch von seinem übergeordneten Element erbt, wird für das Element der Anweisung erstellt. Wenn mehrere Direktiven für dasselbe Element einen neuen Bereich anfordern, wird nur ein neuer Bereich erstellt.

{...} (ein Objekt-Hash): Ein neuer Bereich "isolieren" wird für die Vorlage der Richtlinie erstellt.Der Bereich 'Isolieren' unterscheidet sich vom normalen Gültigkeitsbereich in dadurch, dass er prototypisch nicht vom übergeordneten Bereich erbt. Dies ist nützlich beim Erstellen von wiederverwendbaren Komponenten, die nicht versehentlich Daten im übergeordneten Bereich lesen oder ändern sollten. Beachten Sie, dass eine isolate-Bereichsdirektive ohne Vorlage oder templateUrl nicht den isolate-Bereich auf seine untergeordneten Elemente anwendet.

UPDATE:

Sie verwenden confirm viermal, so dass es die Link-Funktion viermal durchläuft. Jedes Mal, wenn es die Link-Funktion durchläuft, binden Sie einige Funktionen an die Schaltflächen auf der Seite. Die Schaltfläche mit dem Namen termin-bestaetigen hat vier Ereignisse gebunden, dreimal durch die confirm über die tr und einmal über die div. Wenn Sie auf die Schaltfläche klicken, werden alle diese Ereignisse ausgelöst, und in all diesen Ereignissen, die Sie nicht überprüfen, zeigen Sie einfach alles an.

In diesem Fall empfehle ich Ihnen Ihre Richtlinie in mehr Biss Größe Stücke brechen (zumindest trennen die confirm auf den tr ‚s und die div) und einige Funktionen an einen Controller zu lenken. Sie könnten der Direktive confirm ein Attribut hinzufügen, das Sie innerhalb der Direktive betrachten können. Sobald dieses Attribut true ergibt, zeigen/verstecken Sie was auch immer.

+0

Vielen Dank für die detaillierte Erklärung. Für das Verständnis des Problems hat es mir sehr geholfen. Aber jetzt weiß ich nicht, wie ich das in meinem Fall umsetzen soll. Wenn ich nur {} benutze, dann besteht das Problem immer noch. Ich bin ein angularjs Anfänger, also brauche ich weitere Unterstützung. – Codehan25

+0

@Codehan25 Ich habe meinen Beitrag mit einer weiteren Analyse aktualisiert. –

+0

Es funktioniert nicht :( – Codehan25

Verwandte Themen