2015-07-22 12 views
6

Ho già questo codice che mi si avvicinò con:Posso semplificare cliccando sul tasto invio con AngularJS?

Nel mio controller esterno:

$scope.key = function ($event) { 
     $scope.$broadcast('key', $event.keyCode) 
    } 

Nel mio controller interno (ho più di uno come questo)

$scope.$on('key', function (e, key) { 
     if (key == 13) { 
      if (ts.test.current) { 
       var btn = null; 
       if (ts.test.userTestId) { 
        btn = document.getElementById('viewQuestions'); 
       } else { 
        btn = document.getElementById('acquireTest'); 
       } 
       $timeout(function() { 
        btn.focus(); 
        btn.click(); 
        window.setTimeout(function() { 
         btn.blur(); 
        }, 500); 
       }) 
      } 
     } 
    }); 

Is c'è un altro modo in cui posso semplificarlo utilizzando alcune funzionalità di AngularJS che non ho incluso qui?

+0

Si sta utilizzando un modulo sulle pagine che è necessario inserire la funzionalità chiave? –

+0

Dovresti fornire l'usecase. Sicuramente aiuta se otteniamo più informazioni sul contesto. – Okazari

+0

@joe - Non sto utilizzando un modulo perché ho pulsanti diversi che vengono mostrati e nascosti e non un solo pulsante. In questo esempio, ad esempio, faccio qualcosa di diverso a seconda che inf sia impostato o meno l'ID utente. –

risposta

6

prega di consultare questo succo, https://gist.github.com/EpokK/5884263

Si può semplicemente creare una direttiva ng-enter e passaggio la tua azione come parametro

app.directive('ngEnter', function() { 
    return function(scope, element, attrs) { 
    element.bind("keydown keypress", function(event) { 
     if(event.which === 13) { 
     scope.$apply(function(){ 
      scope.$eval(attrs.ngEnter); 
     }); 
     event.preventDefault(); 
     } 
    }); 
    }; 
}); 

HTML

<input ng-enter="myControllerFunction()" /> 

Si può cambiare il nome ng-enter a qualcosa di diverso, perché è un ng-** riservato dal core team angolare.

Inoltre, vedo che il controller ha a che fare con DOM e non dovresti. Sposta quelle logiche in altre direttive o in HTML e mantieni il tuo controller snello.

if (ts.test.userTestId) { 
    btn = document.getElementById('viewQuestions'); //NOT in controller 
} else { 
    btn = document.getElementById('acquireTest'); //NOT in controller 
} 
$timeout(function() { 
    btn.focus();  //NOT in controller 
    btn.click();  //NOT in controller 
    window.setTimeout(function() { // $timeout in $timeout, questionable 
     btn.blur(); //NOT in controller 
    }, 500); 
}) 
2

Quello che ho fatto in passato è una direttiva che ascolta solo inserire gli input chiave e quindi esegue una funzione che gli viene fornita in modo simile a un ng-clic. Ciò fa sì che la logica rimanga nel controller e consenta il riutilizzo su più elementi.

//directive 
angular.module('yourModule').directive('enterHandler', [function() { 
    return{ 
     restrict:'A', 
     link: function (scope, element, attrs) { 
      element.bind("keydown keypress", function (event) { 
       var key = event.which ? event.which : event.keyCode; 
       if (key === 13) { 
        scope.$apply(function() { 
         scope.$eval(attrs.enterHandler); 
        }); 
        event.preventDefault(); 
       } 
      }); 
     } 
    } 
}]); 

quindi il controller diventa

$scope.eventHandler = function(){ 
    if (ts.test.current) { 
      var btn = ts.test.userTestId 
         ? document.getElementById('viewQuestions') 
         : document.getElementById('acquireTest'); 
      $timeout(function() { 
       btn.focus(); 
       btn.click(); 
       window.setTimeout(function() { 
        btn.blur(); 
       }, 500); 
      }) 
     } 
    } 

e il markup può quindi essere

<div enter-handler="eventHandler()" ></div> 
Problemi correlati