Làm cách nào để sử dụng sự kiện nhấn phím trong AngularJS?


410

Tôi muốn bắt sự kiện nhấn phím enter trên hộp văn bản bên dưới. Để làm cho nó rõ ràng hơn, tôi đang sử dụng một ng-repeatđể điền vào người. Đây là 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>

Đây là mô-đun của tôi:

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

Tôi đang sử dụng tài nguyên để điền vào bảng và mã điều khiển của tôi là:

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

1
Là đầu vào bên trong một hình thức?
callmekatootie

1
không .. nó ở trong một cái bàn !!
Venkata Tata

Câu trả lời:


808

Bạn cần thêm một directive, như thế này:

Javascript :

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 Lệnh này liên kết với keydownkeypresscác sự kiện của phần tử mà nó được quy cho. Khi sự kiện được nhận, biểu thức được cung cấp được ước tính bên trong một $applykhối.
Pete Martin

7
An toàn hơn để xác định khóa như thế này: var key = typeof event.which === "undefined" ? event.keyCode : event.which;miễn là sự kiện không được sử dụng bởi mọi trình duyệt. Xem bình luận tại đây: stackoverflow.com/a/4471635/2547632
Gabriel

3
Tôi cũng sẽ thêm keyupvào kiểm tra liên kết
user1713964

59
cũng lưu ý rằng không nên sử dụng tiền tố ng, vì điều này có thể xung đột với các chỉ thị ng- * trong tương lai. Sử dụng của riêng bạn thay vào đó
Marius Balčytis

3
Đừng quên phá hủy các ràng buộc của bạn: scope. $ On ('$
kill

345

Một cách khác là sử dụng chỉ thị tiêu chuẩn ng-keypress="myFunct($event)"

Sau đó, trong bộ điều khiển của bạn, bạn có thể có:

...

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

...

18
Để cứu người khác một thời gian, ng-keypressdường như không phải là một phần của góc 1.0.x, ui-keypress(với ngữ nghĩa gọi hơi khác) có sẵn mặc dù: angular-ui.github.io/ui-utils
Cebjyre

1
Tôi nghĩ rằng nhận xét trên đây là nhằm vào một câu trả lời khác nhau. (Chỉ để tham khảo.)
Cornelius

Martin thực sự là chức năng của bộ điều khiển: để xử lý các sự kiện UI.
Trevor de Koekkoek

5
Tốt hơn nữa, hãy sử dụng ngKeypress và chuyển sự kiện $ vào bộ lọc tùy chỉnh.
Martin

7
Câu trả lời hay nhất +1. Tại sao tôi nên đưa ra chỉ thị của riêng mình, nếu có, đã được đưa vào Angular?
bFunc

179

Cách tiếp cận đơn giản nhất của tôi bằng cách sử dụng chỉ thị xây dựng góc cạnh:

ng-keypress, ng-keydownHoặc ng-keyup.

Thông thường, chúng tôi muốn thêm hỗ trợ bàn phím cho một cái gì đó đã được xử lý bằng ng-click.

ví dụ:

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

Bây giờ, hãy thêm hỗ trợ bàn phím.

kích hoạt bằng phím enter:

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

bằng phím cách:

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

theo không gian hoặc nhập khóa:

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

nếu bạn đang ở trong trình duyệt hiện đại

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

Thông tin thêm về keyCode:
keyCode không được dùng nhưng API được hỗ trợ tốt, bạn có thể sử dụng $ evevt.key trong trình duyệt được hỗ trợ thay thế.
Xem thêm trong https://developer.mozilla.org/en-US/docs/Web/API/PalEvent/key


1
bí mật là điều kiện trước khi phương thức được thực thi $ event.which === 13 && action () - cảm ơn!
dùng12121234

1
'$ event.which' không hoạt động với tôi, nhưng tôi đã tìm thấy '$ event.keyCode' đang hoạt động.
Karl Adler

event.which không được xác định trong IE <9 khi gõ phím và gõ phím.
Eric Chen

2
"Các trình duyệt cũ như IE9" .. không bao giờ nghĩ ngày này sẽ đến :)
Mihnea Belcin 7/2/2017

1
Tại sao không ai cập nhật đoạn mã ở đây để sử dụng $ event.keyCode? Tôi sẽ tự chỉnh sửa nó, nhưng tôi không thể vì một số lý do.
Nathan Hazzard


19

Đây là những gì tôi đã tìm ra khi tôi xây dựng một ứng dụng có yêu cầu tương tự, nó không yêu cầu viết một chỉ thị và nó tương đối đơn giản để nói những gì nó làm:

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

3
Đơn giản và hiệu quả.
Xplouder

15

Bạn có thể sử dụng ng-keydown = "myFunction ($ event)" làm thuộc tính.

<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>

control.js

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

3

Bạn cũng có thể áp dụng nó cho bộ điều khiển trên phần tử cha. Ví dụ này có thể được sử dụng để làm nổi bật một hàng trong bảng bằng cách nhấn các phím mũi tên lên / xuống.

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

Cố gắng

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

không làm gì cho tôi

Strangley mẫu tại https://docs.angularjs.org/api/ng/directive/ngKeypress , mà ng-keypress = "Count = Count + 1", hoạt động.

Tôi tìm thấy một giải pháp thay thế, nhấn Enter để gọi ng-click của nút.

<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')"cũng không làm việc cho tôi, nhưng nếu bạn làm ng-keypress="fooMethod()"và trong bộ điều khiển của bạn $scope.fooMethod = function() { console.log('fooMethod called'); }không hoạt động.
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

Đây là một phần mở rộng về câu trả lời từ EpokK.

Tôi có cùng một vấn đề là phải gọi một hàm phạm vi khi nhập được đẩy trên một trường đầu vào. Tuy nhiên tôi cũng muốn chuyển giá trị của trường đầu vào cho hàm được chỉ định. Đây là giải pháp của tôi:

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();
        }
    });
};

});

Việc sử dụng trong HTML như sau:

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

Kudos đến EpokK cho câu trả lời của mình.


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

1

Cái này thì sao?:

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

Bây giờ khi bạn nhấn phím enter sau khi viết một cái gì đó vào đầu vào của bạn, biểu mẫu biết cách xử lý nó.


Làm thế nào / được chat.sendMessage()định nghĩa
Aaron McMillin

0

Một số ví dụ về mã mà tôi đã làm cho dự án của tôi. Về cơ bản bạn thêm các thẻ vào thực thể của bạn. Hãy tưởng tượng bạn có văn bản đầu vào, khi nhập Tên thẻ bạn sẽ có menu thả xuống với các thẻ được tải sẵn để chọn, bạn điều hướng bằng mũi tên và chọn bằng 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>

Bộ điều khiển.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 + Bootstrap 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
Tôi nghĩ rằng đây là một giải pháp khó chịu. Một bộ điều khiển không nên xử lý những thứ UI như nhấn phím.
Maya Kathrine Andersen

5
Câu trả lời này chứa rất nhiều "tiếng ồn", theo cách nói, chứa rất nhiều đánh dấu - theo như tôi có thể thấy trong nháy mắt - không liên quan đến câu hỏi thực tế trong tay. Có thể cô đọng / hữu ích hơn khi cô đọng mã trong câu trả lời và cung cấp ví dụ đầy đủ trong một ý chính / jsfiddle / plnkr.
Cornelius

1
@MartinAndersen, phím bấm nên được xử lý ở đâu trong một ứng dụng góc cạnh?
Emanegux

1
Khi tôi nhìn vào nó bây giờ có vẻ ổn. Về cơ bản, cách nhấn phím luôn được xử lý với mô hình sự kiện JS.
Maya Kathrine Andersen

0

Tôi hơi muộn .. nhưng tôi đã tìm thấy một giải pháp đơn giản hơn bằng cách sử dụng auto-focus.. Điều này có thể hữu ích cho các nút hoặc khác khi bật dialog:

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

Điều đó sẽ ổn nếu bạn muốn nhấn nút onSpace hoặc Enter click.


câu hỏi là về nhấn enter và làm một cái gì đó.
BlaShadow

0

đây là chỉ thị của tôi:

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();
                }
            });
        }
    };
});

sử dụng:

<input number />

0

bạn có thể sử dụng ng-keydown, ng-keyup, ng-press như thế này.

để triger một chức năng:

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

hoặc nếu bạn có một gia vị, chẳng hạn như khi anh ta nhấn thoát (27 là mã khóa để thoát)

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

0

Tôi nghĩ rằng sử dụng document.bind thanh lịch hơn một chút

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

Để lấy tài liệu đến hàm tạo của bộ điều khiển:

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

Tất cả bạn cần làm để có được sự kiện là như sau:

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

Một chỉ thị có thể làm điều đó, nhưng đó không phải là cách bạn làm điều đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.