trong anglejs làm cách nào để truy cập phần tử đã kích hoạt sự kiện?


93

Tôi sử dụng cả Bootstrap và AngularJS trong ứng dụng web của mình. Tôi đang gặp một số khó khăn để cả hai làm việc cùng nhau.

Tôi có một phần tử, có thuộc tính data-provide="typeahead"

<input id="searchText" ng-model="searchText" type="text"
       class="input-medium search-query" placeholder="title"
       data-provide="typeahead" ng-change="updateTypeahead()" />

Và tôi muốn cập nhật data-sourcethuộc tính khi người dùng nhập vào trường. Hàm updateTypeaheadđược kích hoạt đúng cách, nhưng tôi không có quyền truy cập vào phần tử đã kích hoạt sự kiện, trừ khi tôi sử dụng $('#searchText'), đó là cách jQuery, không phải cách AngularJS.

Cách tốt nhất để AngularJS hoạt động với mô-đun JS kiểu cũ là gì.

Câu trả lời:


60
 updateTypeahead(this)

sẽ không chuyển phần tử DOM cho hàm updateTypeahead(this). Ở đây thissẽ đề cập đến phạm vi. Nếu bạn muốn truy cập sử dụng phần tử DOM updateTypeahead($event). Trong hàm gọi lại, bạn có thể lấy phần tử DOM bằng cách event.target.

Xin lưu ý: hàm ng-change không cho phép chuyển $ event làm biến.


65
ng-change không hỗ trợ đối tượng sự kiện $ event được truyền dưới dạng tham số.
Mark Rajcok

1
Có vẻ như ng-style cũng không hỗ trợ.
laggingreflex

4
Phản đối quá. Không hoạt động cho ng-class. $ sự kiện không được xác định! <li ng-repeat="item in items" role="menuitem" ng-class="{\'selected\' : isSelected($event, item)}">
Saad Benbouzid

4
Vâng, không thực sự trả lời câu hỏi, vì $ event không hoạt động với ng-change: /
Adrian Tombu

1
có lẽ là câu trả lời được đánh giá cao nhất từng thấy trên SO
MatteoSp.

74

Cách Angular chung để có quyền truy cập vào một phần tử đã kích hoạt một sự kiện là viết một chỉ thị và bind () với sự kiện mong muốn:

app.directive('myChange', function() {
  return function(scope, element) {
    element.bind('change', function() {
      alert('change on ' + element);
    });
  };
});

hoặc với DDO (theo nhận xét của @ tpartee bên dưới):

app.directive('myChange', function() {
  return { 
    link:  function link(scope, element) {
      element.bind('change', function() {
        alert('change on ' + element);
      });
    }
  }
});

Chỉ thị trên có thể được sử dụng như sau:

<input id="searchText" ng-model="searchText" type="text" my-change>

Thợ đào móng .

Nhập vào trường văn bản, sau đó để lại / làm mờ. Chức năng gọi lại thay đổi sẽ kích hoạt. Bên trong chức năng gọi lại đó, bạn có quyền truy cập element.

Một số chỉ thị tích hợp hỗ trợ truyền một đối tượng $ event. Vd: ng- * click, ng- Mouse *. Lưu ý rằng ng-change không hỗ trợ sự kiện này.

Mặc dù bạn có thể lấy phần tử thông qua đối tượng $ event:

<button ng-click="clickit($event)">Hello</button>

$scope.clickit = function(e) {
    var elem = angular.element(e.srcElement);
    ...

Điều này đi ngược lại với cách Angular - Misko .


Mặc dù giải pháp của bạn hoạt động tốt, nhưng nó không sử dụng định dạng DDO, điều này khiến bạn rất khó hiểu khi tìm ra cách thêm / chuyển phạm vi vào liên kết. Không có cách nào đơn giản từ ví dụ của bạn để chỉ cần thêm một số đường DDO để xác định phạm vi và điều đó dường như "ngược lại với cách Angular" sâu sắc như việc chuyển $ event từ một ng-click. Trên thực tế, trong tài liệu Angular chính thức và các ví dụ về mã, tôi không thể tìm thấy một ví dụ nào tương tự về mặt cú pháp với của bạn (tức là một chỉ thị chỉ trả về một hàm ẩn danh mà không có bất kỳ DDO nào).
tpartee

@tpartee, điểm tốt. Quay lại khi tôi viết câu trả lời này ban đầu, các tài liệu góc có các ví dụ về các lệnh đơn giản chỉ trả về một hàm ẩn danh (là hàm liên kết). Tôi đồng ý rằng DDO sẽ tốt hơn trong những ngày này. Tôi đã cập nhật câu trả lời.
Mark Rajcok

Tôi nghĩ <button ng-click = "clickit ($ event.srcElement)"> sẽ tốt hơn
Carlos ABS

1
Thời gian trôi qua, tôi càng tin rằng "con đường góc" được overarchitected và overcomplicated
Jacob Stamm

7

bạn có thể dễ dàng nhận được như sự kiện viết đầu tiên này trên phần tử

ng-focus="myfunction(this)"

trong tệp js của bạn như bên dưới

$scope.myfunction= function (msg, $event) {
    var el = event.target
    console.log(el);
}

Tôi cũng đã sử dụng nó.


8
điều này trả về phạm vi, vì vậy điều này sẽ không hoạt động như mong đợi.
vdclouis

1
Điều này không giải quyết được vấn đề của OP. Chắc chắn nó cho phép một hàm biết người được gọi là ai, nhưng điều đó không liên quan đến cuộc gọi ng-change và không có mối liên hệ nào giữa hai hàm. Điều OP cần là có thể tham chiếu đến phần tử đã kích hoạt sự kiện ng-change trong lệnh gọi hàm mà nó thực hiện.
tpartee

Điều này hoạt động bằng cách thêm các thuộc tính (giả sử, id): alert (event.target.id).
Weihui Guo

2

Có một giải pháp sử dụng $ element trong controller nếu bạn không muốn tạo một chỉ thị khác cho sự cố này:

appControllers.controller('YourCtrl', ['$scope', '$timeout', '$element',
        function($scope, $timeout, $element) {

    $scope.updateTypeahead = function() {
       // ... some logic here
       $timeout(function() {
           $element[0].getElementsByClassName('search-query')[0].focus();
           // if you have unique id you can use $window instead of $element:
           // $window.document.getElementById('searchText').focus();
       });
    }
}]);

Và điều này sẽ hoạt động với ng-change :

<input id="searchText" type="text" class="search-query" ng-change="updateTypeahead()" ng-model="searchText" />

0

nếu bạn muốn giá trị ng-model, nếu bạn có thể viết như thế này trong sự kiện được kích hoạt: $ scope.searchText


0

Tôi không chắc bạn đã có phiên bản nào, nhưng câu hỏi này đã được hỏi từ lâu. Hiện tại với Angular 1.5, tôi có thể sử dụng ng-keypresssự kiện và debouncechức năng từ Lodash để mô phỏng hành vi tương tự như ng-changevậy, vì vậy tôi có thể nắm bắt sự kiện $

<input type="text" ng-keypress="edit($event)" ng-model="myModel">

$ scope.edit = _.debounce (function ($ event) {console.log ("$ event", $ event)}, 800)


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.