2013-02-18 6 views
9

Sto usando angularjs scheda ed esempi riquadro componentiAngularJS: come guardare la selezione delle schede?

angular.module('components', []). 
    directive('tabs', function() { 
     return { 
      restrict: 'E', 
      transclude: true, 
      scope: {}, 
      controller: function($scope, $element) { 
       var panes = $scope.panes = []; 

       $scope.select = function(pane) { 
        angular.forEach(panes, function(pane) { 
         pane.selected = false; 
        }); 
        pane.selected = true; 
       } 

       this.addPane = function(pane) { 
        if (panes.length == 0) $scope.select(pane); 
         panes.push(pane); 
        } 
       }, 
       template: 
        '<div class="tabbable">' + 
         '<ul class="nav nav-tabs">' + 
          '<li ng-repeat="pane in panes" ng-class="{active:pane.selected}">'+ 
           '<a href="" ng-click="select(pane)">{{pane.title}}</a>' + 
          '</li>' + 
         '</ul>' + 
         '<div class="tab-content" ng-transclude></div>' + 
        '</div>', 
       replace: true 
      }; 
     }). 
    directive('pane', function() { 
     return { 
      require: '^tabs', 
      restrict: 'E', 
      transclude: true, 
      scope: { title: '@' }, 
      link: function(scope, element, attrs, tabsCtrl) { 
       tabsCtrl.addPane(scope); 
      }, 
      template: 
       '<div class="tab-pane" ng-class="{active: selected}" ng-transclude>' + 
       '</div>', 
      replace: true 
     }; 
    }) 

SomePage.html

<tabs> 
    <pane title="Datos Generales"> 
     <div ng-include src="'/resources/js/page/running/admin/templates/update-data.html'"></div> 
    </pane> 
    <pane title="Localización"> 
     <div ng-include src="'/resources/js/page/running/admin/templates/update-location.html'"></div> 
    </pane> 
    <pane title="Datos Contacto"> 
     <div ng-include src="'/resources/js/page/running/admin/templates/update-contacts.html'"></div> 
    </pane> 
    <pane title="Variantes"> 
     <div ng-include src="'/resources/js/page/running/admin/templates/update-variants.html'"></div> 
    </pane> 
</tabs> 

Nel secondo riquadro c'è un GoogleMap. Vorrei aggiornare la mappa di google quando è selezionato il secondo riquadro.

Non so come ottenere il riquadro selezionato nel controller. Ho provato $scope.panes ma è undefined

+0

Quale controller deve sapere? Un controller che circonda l'elemento tabs? Un controller all'interno di ng-include'd update-location.html? –

+0

Un controller che circonda l'elemento di tabulazione – qopuir

+0

Si noti che a partire da v 0.5 (e possibilmente in precedenza), la direttiva tab può assumere un attributo 'select' che è un attributo '&', valutato nell'ambito genitore, quindi non è più necessario modifica il codice ui-bootstrap. – rych

risposta

7

Qui ci sono tre modi si potrebbe risolvere il problema:

  1. definiscono un metodo sul controller, specificare che il metodo in un attributo sull'elemento schede, utilizzare il '& 'sintassi sulla definizione dell'isolamento dell'isolamento della direttiva tabs per consentire alla direttiva di chiamare il metodo specificato quando viene selezionato un riquadro.
  2. definire un oggetto sull'ambito del controllore con una proprietà "selectedPane". Utilizzare systnax '=' nella definizione dell'isolamento dell'isolamento della direttiva tabs per abilitare il collegamento bidirezionale. Impostare questa proprietà ogni volta che viene selezionato un riquadro.
  3. hanno la direttiva di tabulazione $emit un evento e il controller deve ascoltarlo utilizzando $ on.

Aggiornamento: @qopuir chiesto per maggiori dettagli circa l'opzione 1.
Supponiamo che il metodo di controllo è qualcosa di simile al seguente:

$scope.paneChanged = function(pane) { 
    $scope.selectedPane = pane 
    ... 
} 

Sull'elemento schede, ci specifichiamo questa funzione con l'attributo pane-changed:

<tabs pane-changed="paneChanged(selectedPane)"> 

Quindi, la direttiva schede possono utilizzare il 'Sintassiper chiamare questo metodo:

.directive('tabs', function() { 
    return { 
     restrict: 'E', 
     transclude: true, 
     scope: { paneChanged: '&' }, 
     controller: function($scope, $element) { 
      var panes = $scope.panes = []; 

      $scope.select = function(pane) { 
       angular.forEach(panes, function(pane) { 
        pane.selected = false; 
       }); 
       pane.selected = true; 
       $scope.paneChanged({selectedPane: pane}); 
      } 
+1

Ho provato l'opzione 3, ma c'è ancora un problema. Il listener aggiorna la mappa prima del rendering, quindi la mappa di google viene stampata erroneamente. Come potrebbe essere risolto? Sto usando AngularUI per Google Maps. – qopuir

+1

Se hai una direttiva che gestisce la tua mappa google, aggiungi un controller a quella direttiva e chiedi a $ emettere l'evento dopo il rendering della mappa (si spera che google maps fornisca un callback o qualche evento a cui puoi associare() per sapere quando il rendering è completo.) Nel callback o nel gestore di eventi, assicurati di chiamare $ scope.apply(). Se non hai una callback o un evento da attivare, allora il meglio che puoi fare è usare $ timeout da qualche parte. Il gestore del timeout potrebbe essere chiamato dopo x millisecondi, o forse potrebbe controllare qualcosa nel DOM che indicherebbe che la mappa è resa. –

+1

Finalmente ho usato $ timeout, perché la richiamata non funzionava bene. Ma non sono convinto dell'opzione 3. Preferisco l'opzione 1, ma non so come configurare la direttiva tabs per accettare un metodo che specifica i parametri. Potresti specificare come implementare quella soluzione? – qopuir