AngularJS에서 키 누르기 이벤트를 사용하는 방법은 무엇입니까?


410

아래 텍스트 상자에서 Enter 키 누르기 이벤트를 잡고 싶습니다. 더 명확하게하기 위해 a ng-repeat를 사용 하여 tbody를 채 웁니다. HTML은 다음과 같습니다.

<td><input type="number" id="closeqty{{$index}}" class="pagination-right closefield" 
    data-ng-model="closeqtymodel" data-ng-change="change($index)" required placeholder="{{item.closeMeasure}}" /></td>

이것은 내 모듈입니다.

angular.module('components', ['ngResource']);

리소스를 사용하여 테이블을 채우고 있으며 컨트롤러 코드는 다음과 같습니다.

function Ajaxy($scope, $resource) {
//controller which has resource to populate the table 
}

1
입력이 양식 안에 있습니까?
callmekatootie

1
아니 .. 그 테이블에!
Venkata Tata

답변:


808

다음 directive과 같이 를 추가해야합니다 .

자바 스크립트 :

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

                event.preventDefault();
            }
        });
    };
});

HTML :

<div ng-app="" ng-controller="MainCtrl">
    <input type="text" my-enter="doSomething()">    
</div>

7
@DerekAdair 지시어 는 그 요소가 속한 요소 keydownkeypress이벤트에 바인딩 합니다. 이벤트가 수신되면 제공된 표현식이 $apply블록 내에서 평가됩니다 .
피트 마틴

7
var key = typeof event.which === "undefined" ? event.keyCode : event.which;모든 브라우저에서 event.this를 사용하지 않는 한 다음 과 같이 키를 정의하는 것이 더 안전 합니다. 여기에 의견보기 : stackoverflow.com/a/4471635/2547632
Gabriel

3
나는 또한 keyup바인드 테스트에 추가 할 것이다
user1713964

59
또한 ng 접두사를 사용하는 것은 권장되지 않습니다. 이는 향후 ng- * 지시문과 충돌 할 수 있기 때문입니다. 대신 직접 사용
Marius Balčytis

3
바인딩을 파기하는 것을 잊지 마십시오 : scope. $ on ( '$ destroy', function () {element.unbind ( 'keydown');})
nawlbergs

345

대안은 표준 지시문을 사용하는 것입니다 ng-keypress="myFunct($event)"

그런 다음 컨트롤러에서 다음을 수행 할 수 있습니다.

...

$scope.myFunct = function(keyEvent) {
  if (keyEvent.which === 13)
    alert('I am an alert');
}

...

18
다른 사람을 시간을 절약하기 위해 ng-keypress앵귤러 1.0.x의 일부인 것처럼 보이지는 않지만 ui-keypress약간 다른 호출 의미론을 사용할 수 있습니다. angular-ui.github.io/ui-utils
Cebjyre

1
위의 의견은 다른 답변을 목표로했다고 생각합니다. (참고로 참조)
Cornelius

Martin은 실제로 컨트롤러의 기능입니다. UI 이벤트를 처리합니다.
Trevor de Koekkoek

5
더 나은 방법은 ngKeypress를 사용하고 $ event를 사용자 정의 필터에 전달하는 것입니다.
Martin

7
최고의 답변 +1. Angular에 이미 포함 된 지시문이있는 경우 왜 직접 지시해야합니까?
bFunc

179

각도 내장 지시문을 사용하는 가장 간단한 방법은 다음과 같습니다.

ng-keypress, ng-keydown또는 ng-keyup.

일반적으로 ng-click으로 이미 처리 된 키보드 지원을 추가하려고합니다.

예를 들어 :

<a ng-click="action()">action</a>

이제 키보드 지원을 추가하겠습니다.

Enter 키로 트리거하십시오.

<a ng-click="action()" 
   ng-keydown="$event.keyCode === 13 && action()">action</a>

스페이스 키로 :

<a ng-click="action()" 
   ng-keydown="$event.keyCode === 32 && action()">action</a>

공백으로 또는 키를 입력하십시오.

<a ng-click="action()" 
   ng-keydown="($event.keyCode === 13 || $event.keyCode === 32) && action()">action</a>

최신 브라우저를 사용하는 경우

<a ng-click="action()" 
   ng-keydown="[13, 32].includes($event.keyCode) && action()">action</a>

keyCode에 대한 추가 정보 :
keyCode는 더 이상 사용되지 않지만 잘 지원되는 API이므로 지원되는 브라우저에서 $ evevt.key를 대신 사용할 수 있습니다. https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key
에서 자세한 내용을 참조하십시오


1
비밀은 메소드가 실행되기 전에 조건부입니다. $ event.which === 13 && action ()-감사합니다!
user12121234

1
'$ event.which'가 작동하지 않지만 작동하는 '$ event.keyCode'를 찾았습니다.
Karl Adler

keydown 및 keyup에 대해 IE <9에서 정의되지 않은 event.
Eric Chen

2
"IE9와 같은 오래된 브라우저는":) 이런 날이 올 것이다 생각하지 않습니다 ..
Mihnea Belcin

1
그렇다면 왜 $ event.keyCode를 사용하도록 코드 스 니펫을 업데이트하지 않았습니까? 직접 편집했지만 어떤 이유로 든 할 수 없습니다.
Nathan Hazzard

102

또 다른 간단한 대안 :

<input ng-model="edItem" type="text" 
    ng-keypress="($event.which === 13)?foo(edItem):0"/>

그리고 ng-ui 대안 :

<input ng-model="edItem" type="text" ui-keypress="{'enter':'foo(edItem)'}"/>

9
: NG-UI 대신 당신이 "UI.Utils"를 말하거나 링크를 공유해야합니다, 모호한 angular-ui.github.io/ui-utils
파울로 올리베이라

ui-utils는 더 이상 사용되지 않는 것 같습니다
cafesanu

19

비슷한 요구 사항으로 앱을 만들 때 알아 낸 것은 다음과 같습니다. 지시문을 작성할 필요가 없으며 수행하는 작업을 말하기가 비교적 간단합니다.

<input type="text" ng-keypress="($event.charCode==13)?myFunction():return" placeholder="Will Submit on Enter">

3
간단하고 효과적입니다.
Xplouder

15

ng-keydown = "myFunction ($ event)"을 속성으로 사용할 수 있습니다 .

<input ng-keydown="myFunction($event)" type="number">

myFunction(event) {
    if(event.keyCode == 13) {   // '13' is the key code for enter
        // do what you want to do when 'enter' is pressed :)
    }
}

5

html

<textarea id="messageTxt" 
    rows="5" 
    placeholder="Escriba su mensaje" 
    ng-keypress="keyPressed($event)" 
    ng-model="smsData.mensaje">
</textarea>

controller.js

$scope.keyPressed = function (keyEvent) {
    if (keyEvent.keyCode == 13) {
        alert('presiono enter');
        console.log('presiono enter');
    }
};

3

부모 요소의 컨트롤러에 적용 할 수도 있습니다. 이 예는 위 / 아래 화살표 키를 눌러 테이블에서 행을 강조 표시하는 데 사용할 수 있습니다.

app.controller('tableCtrl', [ '$scope', '$element', function($scope, $element) {
  $scope.index = 0; // row index
  $scope.data = []; // array of items
  $scope.keypress = function(offset) {
    console.log('keypress', offset);
    var i = $scope.index + offset;
    if (i < 0) { i = $scope.data.length - 1; }
    if (i >= $scope.data.length) { i = 0; }
  };
  $element.bind("keydown keypress", function (event) {
    console.log('keypress', event, event.which);
    if(event.which === 38) { // up
      $scope.keypress(-1);
    } else if (event.which === 40) { // down
      $scope.keypress(1);
    } else {
      return;
    }
    event.preventDefault();
  });
}]);


<table class="table table-striped" ng-controller="tableCtrl">
<thead>
    <tr>
        <th ng-repeat="(key, value) in data[0]">{{key}}</th>
    </tr>
</thead>
<tbody>
    <tr ng-repeat="row in data track by $index" ng-click="draw($index)" ng-class="$index == index ? 'info' : ''">
        <td ng-repeat="(key, value) in row">{{value}}</td>
    </tr>
</tbody>
</table>


3

견딜 수 없는

ng-keypress="console.log($event)"
ng-keypress="alert(123)"

나를 위해 아무것도하지 않았다.

ng-keypress = "count = count + 1"을 수행하는 https://docs.angularjs.org/api/ng/directive/ngKeypress 의 샘플을 Strangley가 작동합니다.

Enter를 누르면 버튼의 ng-click을 호출하는 대체 솔루션을 찾았습니다.

<input ng-model="..." onkeypress="if (event.which==13) document.getElementById('button').click()"/>
<button id="button" ng-click="doSomething()">Done</button>

ng-keypress="console.log('foo')"나에게도 효과가 없었지만 ng-keypress="fooMethod()"컨트롤러를 사용 하면 컨트롤러 $scope.fooMethod = function() { console.log('fooMethod called'); }가 작동합니다.
GraehamF

3
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
Informe your name:<input type="text" ng-model="pergunta" ng-keypress="pressionou_enter($event)" ></input> 
<button ng-click="chamar()">submit</button>
<h1>{{resposta}}</h1> 
</div>
<script>
var app = angular.module('myApp', []);
//create a service mitsuplik
app.service('mitsuplik', function() {
    this.myFunc = function (parametro) {
        var tmp = ""; 
        for (var x=0;x<parametro.length;x++)
            {
            tmp = parametro.substring(x,x+1) + tmp;
            } 
        return tmp;
    }
});
//Calling our service
app.controller('myCtrl', function($scope, mitsuplik) { 
  $scope.chamar = function() { 
        $scope.resposta = mitsuplik.myFunc($scope.pergunta); 
    };
  //if mitsuplik press [ENTER], execute too
  $scope.pressionou_enter = function(keyEvent) {
             if (keyEvent.which === 13) 
                { 
                $scope.chamar();
                }

    }
});
</script>
</body>
</html>

2

이것은 EpokK의 답변에 대한 확장입니다.

입력 필드에서 enter를 누를 때 스코프 함수를 호출 해야하는 것과 동일한 문제가있었습니다. 그러나 입력 필드값을 지정된 함수 에 전달하고 싶습니다 . 이것은 내 솔루션입니다.

app.directive('ltaEnter', function () {
return function (scope, element, attrs) {
    element.bind("keydown keypress", function (event) {
        if(event.which === 13) {
          // Create closure with proper command
          var fn = function(command) {
            var cmd = command;
            return function() {
              scope.$eval(cmd);
            };
          }(attrs.ltaEnter.replace('()', '("'+ event.target.value +'")' ));

          // Apply function
          scope.$apply(fn);

          event.preventDefault();
        }
    });
};

});

HTML에서의 사용은 다음과 같습니다.

<input type="text" name="itemname" lta-enter="add()" placeholder="Add item"/>

그의 답변을 위해 EpokK에 Kudos.


<input type="text" name="itemname" ng-model="item.itemname" lta-enter="add(item.itemname)" placeholder="Add item"/>
aycanadal 2019

1

이건 어때?

<form ng-submit="chat.sendMessage()">
    <input type="text" />
    <button type="submit">
</form>

입력 내용을 작성한 후 Enter 키를 누르면 양식을 처리하는 방법을 알 수 있습니다.


chat.sendMessage()정의 / 어떻게 정의
Aaron McMillin

0

프로젝트에서 수행 한 코드의 예입니다. 기본적으로 엔티티에 태그를 추가합니다. 태그 이름을 입력 할 때 사전로드 된 태그가있는 드롭 다운 메뉴를 선택하고 화살표로 이동 한 후 Enter를 사용하여 입력 텍스트를 입력했다고 가정합니다.

HTML + AngularJS v1.2.0-rc.3

    <div>
        <form ng-submit="addTag(newTag)">
            <input id="newTag" ng-model="newTag" type="text" class="form-control" placeholder="Enter new tag"
                   style="padding-left: 10px; width: 700px; height: 33px; margin-top: 10px; margin-bottom: 3px;" autofocus
                   data-toggle="dropdown"
                   ng-change="preloadTags()"
                   ng-keydown="navigateTags($event)">
            <div ng-show="preloadedTags.length > 0">
                <nav class="dropdown">
                    <div class="dropdown-menu preloadedTagPanel">
                        <div ng-repeat="preloadedTag in preloadedTags"
                             class="preloadedTagItemPanel"
                             ng-class="preloadedTag.activeTag ? 'preloadedTagItemPanelActive' : '' "
                             ng-click="selectTag(preloadedTag)"
                             tabindex="{{ $index }}">
                            <a class="preloadedTagItem"
                               ng-class="preloadedTag.activeTag ? 'preloadedTagItemActive' : '' "
                               ng-click="selectTag(preloadedTag)">{{ preloadedTag.label }}</a>
                        </div>
                    </div>
                </nav>
            </div>
        </form>
    </div>

Controller.js

$scope.preloadTags = function () {
    var newTag = $scope.newTag;
    if (newTag && newTag.trim()) {
        newTag = newTag.trim().toLowerCase();

        $http(
            {
                method: 'GET',
                url: 'api/tag/gettags',
                dataType: 'json',
                contentType: 'application/json',
                mimeType: 'application/json',
                params: {'term': newTag}
            }
        )
            .success(function (result) {
                $scope.preloadedTags = result;
                $scope.preloadedTagsIndex = -1;
            }
        )
            .error(function (data, status, headers, config) {
            }
        );
    } else {
        $scope.preloadedTags = {};
        $scope.preloadedTagsIndex = -1;
    }
};

function checkIndex(index) {
    if (index > $scope.preloadedTags.length - 1) {
        return 0;
    }
    if (index < 0) {
        return $scope.preloadedTags.length - 1;
    }
    return index;
}

function removeAllActiveTags() {
    for (var x = 0; x < $scope.preloadedTags.length; x++) {
        if ($scope.preloadedTags[x].activeTag) {
            $scope.preloadedTags[x].activeTag = false;
        }
    }
}

$scope.navigateTags = function ($event) {
    if (!$scope.newTag || $scope.preloadedTags.length == 0) {
        return;
    }
    if ($event.keyCode == 40) {  // down
        removeAllActiveTags();
        $scope.preloadedTagsIndex = checkIndex($scope.preloadedTagsIndex + 1);
        $scope.preloadedTags[$scope.preloadedTagsIndex].activeTag = true;
    } else if ($event.keyCode == 38) {  // up
        removeAllActiveTags();
        $scope.preloadedTagsIndex = checkIndex($scope.preloadedTagsIndex - 1);
        $scope.preloadedTags[$scope.preloadedTagsIndex].activeTag = true;
    } else if ($event.keyCode == 13) {  // enter
        removeAllActiveTags();
        $scope.selectTag($scope.preloadedTags[$scope.preloadedTagsIndex]);
    }
};

$scope.selectTag = function (preloadedTag) {
    $scope.addTag(preloadedTag.label);
};

CSS + 부트 스트랩 v2.3.2

.preloadedTagPanel {
    background-color: #FFFFFF;
    display: block;
    min-width: 250px;
    max-width: 700px;
    border: 1px solid #666666;
    padding-top: 0;
    border-radius: 0;
}

.preloadedTagItemPanel {
    background-color: #FFFFFF;
    border-bottom: 1px solid #666666;
    cursor: pointer;
}

.preloadedTagItemPanel:hover {
    background-color: #666666;
}

.preloadedTagItemPanelActive {
    background-color: #666666;
}

.preloadedTagItem {
    display: inline-block;
    text-decoration: none;
    margin-left: 5px;
    margin-right: 5px;
    padding-top: 5px;
    padding-bottom: 5px;
    padding-left: 20px;
    padding-right: 10px;
    color: #666666 !important;
    font-size: 11px;
}

.preloadedTagItem:hover {
    background-color: #666666;
}

.preloadedTagItemActive {
    background-color: #666666;
    color: #FFFFFF !important;
}

.dropdown .preloadedTagItemPanel:last-child {
    border-bottom: 0;
}

2
나는 이것이 불쾌한 해결책이라고 생각한다. 컨트롤러는 키 누르기와 같은 UI를 처리해서는 안됩니다.
Maya Kathrine Andersen

5
이 답변에는 많은 "소음"이 포함되어 있습니다. 한 눈에 볼 수있는 한, 실제 질문과 관련이없는 많은 마크 업이 포함되어 있습니다. 답변에 코드를 요약하고 gist / jsfiddle / plnkr에 전체 예제를 제공하는 것이 더 간결하고 유용 할 수 있습니다.
Cornelius

1
@ MartinAndersen, 각도 앱에서 키 누르기를 어디에서 처리해야합니까?
Emanegux

1
내가 지금 보면 괜찮아 보입니다. 기본적으로 JS 이벤트 모델에서 키 누르기가 항상 처리되는 방식입니다.
Maya Kathrine Andersen

0

나는 조금 늦었지만 ..를 사용하여 더 간단한 해결책을 찾았습니다 auto-focus.. 이것은 버튼이나 다른 팝업에 유용 할 수 있습니다 dialog:

<button auto-focus ng-click="func()">ok</button>

onSpace 또는 Enter 클릭 버튼을 누르면 괜찮습니다 .


프레스 엔터에 관한 질문은 뭔가를 입력하십시오.
BlaShadow

0

여기 내 지시 사항이 있습니다.

mainApp.directive('number', function () {
    return {
        link: function (scope, el, attr) {
            el.bind("keydown keypress", function (event) {
                //ignore all characters that are not numbers, except backspace, delete, left arrow and right arrow
                if ((event.keyCode < 48 || event.keyCode > 57) && event.keyCode != 8 && event.keyCode != 46 && event.keyCode != 37 && event.keyCode != 39) {
                    event.preventDefault();
                }
            });
        }
    };
});

용법:

<input number />

0

ng-keydown, ng-keyup, ng-press such as를 사용할 수 있습니다.

함수를 심사하려면 :

   <input type="text" ng-keypress="function()"/>

또는 탈출을 누를 때와 같은 조건이있는 경우 (27이 탈출의 핵심 코드 임)

 <form ng-keydown=" event.which=== 27?cancelSplit():0">
....
</form>

0

document.bind를 사용하는 것이 조금 더 우아하다고 생각합니다.

constructor($scope, $document) {
  var that = this;
  $document.bind("keydown", function(event) {
    $scope.$apply(function(){
      that.handleKeyDown(event);
    });
  });
}

컨트롤러 생성자에게 문서를 가져 오려면 :

controller: ['$scope', '$document', MyCtrl]

0
(function(angular) {
  'use strict';
angular.module('dragModule', [])
  .directive('myDraggable', ['$document', function($document) {
    return {
      link: function(scope, element, attr) {
         element.bind("keydown keypress", function (event) {
           console.log('keydown keypress', event.which);
            if(event.which === 13) {
                event.preventDefault();
            }
        });
      }
    };
  }]);
})(window.angular);

0

이벤트를 받기 위해해야 ​​할 일은 다음과 같습니다.

console.log(angular.element(event.which));

지시문은 할 수 그것을 할,하지만하지 어떻게 해.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.