ใน angularjs จะเข้าถึงองค์ประกอบที่เรียกเหตุการณ์ได้อย่างไร?


93

ฉันใช้ทั้ง Bootstrap และ AngularJS ในเว็บแอปของฉัน ฉันมีปัญหาในการทำให้ทั้งสองคนทำงานร่วมกัน

ฉันมีองค์ประกอบซึ่งมีแอตทริบิวต์ data-provide="typeahead"

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

และฉันต้องการอัปเดตdata-sourceแอตทริบิวต์เมื่อผู้ใช้ป้อนข้อมูลในฟิลด์ ฟังก์ชันupdateTypeaheadถูกทริกเกอร์อย่างถูกต้อง แต่ฉันไม่สามารถเข้าถึงองค์ประกอบที่ทำให้เกิดเหตุการณ์ได้เว้นแต่ฉันจะใช้$('#searchText')ซึ่งเป็นวิธี jQuery ไม่ใช่วิธี AngularJS

วิธีใดที่ดีที่สุดในการทำให้ AngularJS ทำงานกับโมดูล JS แบบเก่า

คำตอบ:


59
 updateTypeahead(this)

จะไม่ผ่านองค์ประกอบ DOM updateTypeahead(this)เพื่อฟังก์ชั่น ในที่thisนี้จะกล่าวถึงขอบเขต หากคุณต้องการที่จะเข้าถึงการใช้องค์ประกอบ DOM updateTypeahead($event)ในฟังก์ชั่นการโทรกลับที่คุณจะได้รับองค์ประกอบ DOM event.targetโดย

โปรดทราบ: ฟังก์ชัน ng-change ไม่อนุญาตให้ส่ง $ event เป็นตัวแปร


65
ng-change ไม่สนับสนุนเหตุการณ์ object $ ที่ถูกส่งผ่านเป็นพารามิเตอร์
Mark Rajcok

1
ng-style ไม่รองรับเช่นกัน
laggingreflex

4
โหวตลงด้วย ใช้ไม่ได้กับ ng-class $ เหตุการณ์ไม่ได้กำหนด! <li ng-repeat="item in items" role="menuitem" ng-class="{\'selected\' : isSelected($event, item)}">
Saad Benbouzid

4
ใช่ไม่ตอบคำถามจริงๆเนื่องจาก $ event ไม่ทำงานกับ ng-change: /
Adrian Tombu

1
อาจเป็นคำตอบที่ได้รับคะแนนสูงที่สุดเท่าที่เคยมีมาใน SO
MatteoSp

74

วิธีทั่วไปเชิงมุมในการเข้าถึงองค์ประกอบที่ทำให้เกิดเหตุการณ์คือการเขียนคำสั่งและผูก () ไปยังเหตุการณ์ที่ต้องการ:

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

หรือกับ DDO (ตามความคิดเห็นของ @ tpartee ด้านล่าง):

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

คำสั่งข้างต้นสามารถใช้ได้ดังนี้:

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

Plunker .

พิมพ์ลงในช่องข้อความจากนั้นปล่อย / เบลอ ฟังก์ชันการโทรกลับการเปลี่ยนแปลงจะเริ่มทำงาน ภายในฟังก์ชันการโทรกลับคุณสามารถเข้าถึงelementได้

คำสั่งในตัวบางคำสั่งรองรับการส่งผ่านวัตถุ $ เหตุการณ์ เช่น ng- * click, ng-Mouse * โปรดทราบว่า ng-change ไม่รองรับเหตุการณ์นี้

แม้ว่าคุณจะได้รับองค์ประกอบผ่านทาง $ event object:

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

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

นี้ไป "ลึกกับทางเชิงมุม" - Misko


แม้ว่าโซลูชันของคุณจะใช้งานได้ แต่ก็ไม่ได้ใช้รูปแบบ DDO ซึ่งทำให้สับสนมากในการคิดวิธีเพิ่ม / ส่งผ่านขอบเขตไปยังการเชื่อมโยง ไม่มีวิธีง่ายๆจากตัวอย่างของคุณเพียงแค่เพิ่มน้ำตาล DDO สำหรับการกำหนดขอบเขตและดูเหมือนว่าจะ "เทียบกับวิธีเชิงมุม" อย่างลึกซึ้งเท่ากับการส่งเหตุการณ์ $ จาก ng-click ในความเป็นจริงในเอกสาร Angular อย่างเป็นทางการและตัวอย่างโค้ดฉันไม่พบตัวอย่างเดียวที่คล้ายกับของคุณ (เช่นคำสั่งที่ส่งคืนเฉพาะฟังก์ชันที่ไม่ระบุตัวตนโดยไม่มี DDO)
tpartee

@tpartee จุดดี. ย้อนกลับไปตอนที่ฉันเขียนคำตอบนี้ในตอนแรกเอกสารเชิงมุมมีตัวอย่างของคำสั่งง่ายๆที่ส่งคืนฟังก์ชันที่ไม่ระบุตัวตน (ซึ่งก็คือฟังก์ชันลิงก์) ฉันยอมรับว่า DDO น่าจะดีกว่าในทุกวันนี้ ฉันอัปเดตคำตอบแล้ว
Mark Rajcok

ฉันคิดว่า <button ng-click = "clickit ($ event.srcElement)"> น่าจะดีกว่า
Carlos ABS

1
เมื่อเวลาผ่านไปฉันเชื่อมั่นมากขึ้นเรื่อย ๆ ว่า "ทางเชิงมุม" นั้นมีความซับซ้อนและซับซ้อนมากขึ้นเรื่อย ๆ
Jacob Stamm

7

คุณจะได้รับอย่างง่ายดายเช่นเหตุการณ์เขียนครั้งแรกนี้ในองค์ประกอบ

ng-focus="myfunction(this)"

และในไฟล์ js ของคุณเช่นด้านล่าง

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

ฉันได้ใช้มันเช่นกัน


8
สิ่งนี้ส่งคืนขอบเขตดังนั้นจึงไม่ได้ผลตามที่คาดไว้
vdclouis

1
สิ่งนี้ไม่ได้ช่วยแก้ปัญหาของ OP เลย แน่นอนว่ามันช่วยให้ฟังก์ชั่นหนึ่งรู้ว่าใครถูกเรียก แต่นั่นไม่มีผลต่อการโทร ng-change และไม่มีการเชื่อมต่อระหว่างทั้งสอง สิ่งที่ OP ต้องการคือสามารถอ้างอิงองค์ประกอบที่ทริกเกอร์เหตุการณ์ ng-change ภายในฟังก์ชันที่เรียกใช้
tpartee

ซึ่งทำงานได้โดยการเพิ่มแอตทริบิวต์ (เช่น id): alert (event.target.id)
Weihui Guo

2

มีวิธีแก้ไขโดยใช้องค์ประกอบ $ ในคอนโทรลเลอร์หากคุณไม่ต้องการสร้างคำสั่งอื่นสำหรับปัญหานี้:

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

และสิ่งนี้จะใช้ได้กับng-change :

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

0

หากคุณต้องการค่า ng-model หากคุณสามารถเขียนเช่นนี้ในเหตุการณ์ที่ถูกเรียก: $ scope.searchText


0

ฉันไม่แน่ใจว่าคุณมีรุ่นไหน แต่คำถามนี้ถามเมื่อนานมาแล้ว ขณะนี้ใช้ Angular 1.5 ฉันสามารถใช้ng-keypressเหตุการณ์และdebounceฟังก์ชันจากLodashเพื่อเลียนแบบพฤติกรรมที่คล้ายกันng-changeได้ดังนั้นฉันจึงสามารถจับภาพเหตุการณ์ $ ได้

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

$ scope.edit = _.debounce (ฟังก์ชัน ($ event) {console.log ("$ event", $ event)}, 800)


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.