การเข้าถึงองค์ประกอบที่ถูกคลิกในเชิงมุม


173

ฉันค่อนข้างใหม่กับ AngularJS และสงสัยว่าฉันไม่เข้าใจแนวคิด ฉันใช้ Twitter Bootstrap และฉันโหลด jQuery แล้ว

เวิร์กโฟลว์: ผู้ใช้คลิกลิงก์จากรายการส่วน "master" จะได้รับการอัปเดตและผู้ใช้ลิงก์จะได้รับคลาสที่ใช้งานอยู่

มาร์กอัป HTML พื้นฐาน:

<ul class="list-holder" ng-controller="adminController">
   <li><a ng-click="setMaster('client')">Clients</li>
   <li><a ng-click="setMaster('employees')">Employees</li>
   <li><a ng-click="setMaster('etc')>Etc...</li>
</ul>

ทำสิ่งนี้ใน jQuery:

jQuery(".list-holder").on('click', 'a', function(event){
    event.preventDefault();
jQuery(".list-holder li").removeClass('active');
jQuery(this).parent('li').addClass('active');
});

แต่ฉันไม่สามารถหาวิธีรวม Angular และ jQuery เพื่อทำสิ่งนี้ได้เนื่องจากฉันใช้ Angular เพื่อดึงรายการหลัก (ในรูปแบบ JSON) จากเซิร์ฟเวอร์และอัปเดตรายการในหน้า

ฉันจะรวมสิ่งนี้ได้อย่างไร ฉันไม่สามารถหาองค์ประกอบที่ฉันคลิกได้เมื่อฉันอยู่ในฟังก์ชันตัวควบคุมเชิงมุม

ควบคุม:

function adminController($scope)
    {    
        $scope.setMaster = function(obj)
        {
            // How do I get clicked element's parent li?
            console.log(obj);
        }
    }

คำตอบ:


283

ในขณะที่ AngularJS ช่วยให้คุณได้รับเหตุการณ์คลิก (และทำให้เป้าหมายของมัน) ด้วยไวยากรณ์ต่อไปนี้ (หมายเหตุ$eventอาร์กิวเมนต์ของsetMasterฟังก์ชั่นเอกสารที่นี่: http://docs.angularjs.org/api/ng.directive : ngClick ):

function AdminController($scope) {    
  $scope.setMaster = function(obj, $event){
    console.log($event.target);
  }
}

นี่ไม่ใช่วิธีการเชิงมุมในการแก้ปัญหานี้ ด้วย AngularJS โฟกัสอยู่ที่การจัดการโมเดล หนึ่งจะกลายพันธุ์แบบจำลองและปล่อยให้ AngularJS คิดการเรนเดอร์

วิธี AngularJS ในการแก้ปัญหานี้ (โดยไม่ใช้ jQuery และไม่จำเป็นต้องผ่านการ$eventโต้แย้ง ) จะเป็น:

<div ng-controller="AdminController">
    <ul class="list-holder">
        <li ng-repeat="section in sections" ng-class="{active : isSelected(section)}">
            <a ng-click="setMaster(section)">{{section.name}}</a>
        </li>
    </ul>
    <hr>
    {{selected | json}}
</div>

โดยที่เมธอดในคอนโทรลเลอร์จะมีลักษณะเช่นนี้:

$scope.setMaster = function(section) {
    $scope.selected = section;
}

$scope.isSelected = function(section) {
    return $scope.selected === section;
}

นี่คือ jsFiddle ที่สมบูรณ์: http://jsfiddle.net/pkozlowski_opensource/WXJ3p/15/


198
FYI: $ event ใช้งานไม่ได้เว้นแต่ว่าผ่านมาร์กอัป: ng-click="setMaster(section, $event)"แค่หัวขึ้น
เบ็นเลช

4
ไม่ได้จริงๆมันต้องผ่านเข้าไปในฟังก์ชั่น ในความเป็นจริงแล้วอาจไม่ใช่ความคิดที่ดีที่สุดในการอ้างอิงข้อมูลเฉพาะของ dom เช่นนี้ในคอนโทรลเลอร์ โดยทั่วไปเมื่อมีการใช้งาน $ event ในบริบทของการหยุดการเผยแพร่หรือสิ่งที่ชอบ: <a ng-click="doSomething(); $event.stopPropagation()">Click Just Me</a>
เบ็นเลช

9
ฉันมีปัญหาในการใช้งาน $ event.target เพราะฉันมีไอคอนอยู่ภายในปุ่ม ดังนั้นบางครั้งผลลัพธ์เป้าหมายคือปุ่มและบางครั้งก็เป็นไอคอน (ขึ้นอยู่กับที่ฉันคลิก) ฉันใช้ $ event.currentTarget แทนที่จะเป็นเป้าหมายและใช้งานได้อย่างมีเสน่ห์
lao

4
แม้ว่าการใช้$event.targetแบบนี้อาจไม่ใช่ "เชิงมุม" ฉันรู้สึกเหมือนมีng-repeatรายการขนาดใหญ่ที่มีทุกรายการที่ต้องการผู้ฟังเพื่อประเมินการเปลี่ยนแปลงที่ไม่ได้มีประสิทธิภาพ? การคลิกองค์ประกอบเดียวจะหมายถึงทุกรายการในรายการทั้งหมดต้องได้รับการประเมินใหม่ใช่มั้ย - ทำไมไม่เพียงแค่กำหนดเป้าหมายให้ไอเท็มหนึ่งรายการ$event.targetเพื่อสลับคลาส CSS เช่น คุณคิดอย่างไร? ฉันกำลังทำงานกับแอพ Phonegap และต้องบีบการแสดงทุกครั้งที่ฉันสามารถทำได้
แบรดลีย์ท่วม

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