Làm cách nào để tạo một chỉ thị AngularJS để stopPropagation?


76

Tôi đang cố gắng "stopPropagation" để ngăn trình đơn thả xuống của thanh điều hướng Twitter Bootstrap đóng khi một phần tử (liên kết) bên trong một li được nhấp vào. Sử dụng phương pháp này dường như là giải pháp phổ biến .

Trong Angular, có vẻ như một chỉ thị là nơi để làm điều này? Vì vậy, tôi có:

// do not close dropdown on click
directives.directive('stopPropagation', function () {
    return {
        link:function (elm) {            
            $(elm).click(function (event) {                
                event.stopPropagation();
            });
        }
    };
});

... nhưng phương thức không thuộc phần tử:

TypeError: Object [object Object] has no method 'stopPropagation'

Tôi tuân theo chỉ thị với

<li ng-repeat="foo in bar">
  <div>
    {{foo.text}}<a stop-propagation ng-click="doThing($index)">clickme</a>
  </div>
</li>

Bất kỳ đề xuất?


Bạn nên tạo khoảng trống trong các thẻ cho javascript (hoặc thậm chí là jquery ).
Joseph Silber,

Gợi ý tốt. Đã thực hiện chỉnh sửa.
Robert Christian

Lý do event.stopPropagation()không hoạt động trong mã của bạn là AngularJS và jQuery có hai chu kỳ sự kiện riêng biệt . Đó là một lý do tại sao nói chung là một ý tưởng tồi nếu sử dụng cả hai. Sự kiện nhấp chuột của bạn được xác định bằng cách ngClicksử dụng Angular, nhưng bạn đang cố gắng sử dụng jQuery để dừng truyền sự kiện.
Josh David Miller

Câu trả lời:


156

Tôi đã sử dụng cách này: Đã tạo một chỉ thị:

    .directive('stopEvent', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attr) {
                if(attr && attr.stopEvent)
                    element.bind(attr.stopEvent, function (e) {
                        e.stopPropagation();
                    });
            }
        };
     });

có thể được sử dụng theo cách này:

<a ng-click='expression' stop-event='click'>

Đây là cách chung chung hơn để ngừng lan truyền bất kỳ loại sự kiện nào.


BTW, bạn có thể giải thích thêm về từ khóa hạn chế không? Không tìm thấy một nguồn tốt cho những gì điều đó có nghĩa là chính xác.
Robert Christian

Chắc chắn rồi! docs.angularjs.org/guide/directive "Đối tượng Định nghĩa Chỉ thị": hạn chế - Chuỗi tập hợp con của EACM hạn chế chỉ thị trong một kiểu khai báo chỉ thị cụ thể. Nếu các chỉ thị bị bỏ qua chỉ được phép trên các thuộc tính.
Valentyn Shybanov

Đây là một cách tiếp cận thú vị ... Tôi thích nó. Cảm ơn!
incutonez

1
Giải pháp tương tự cho .prefentDefault () trong IE7 để ngăn việc tải lại trang xảy ra. Giải pháp tuyệt vời!
Malkus

1
Oh chúa tôi chỉ tình yêu
Deminetix

123

"Hiện tại, một số lệnh (tức là ng: click) ngừng truyền sự kiện. Điều này ngăn cản khả năng tương tác với các khuôn khổ khác dựa vào việc nắm bắt các sự kiện như vậy." - liên kết

... và có thể sửa mà không cần chỉ thị và chỉ cần làm:

<a ng-click="doThing($index); $event.stopPropagation();">x</a>

4
Điều này là hoàn hảo. Tôi đã có một danh sách thả xuống với một biểu mẫu trong đó. Tôi đã thêm ng-click = "$ event.stopPropagation ()" vào div xung quanh biểu mẫu và điều đó đã sửa lỗi thả xuống biến mất khi các đầu vào biểu mẫu được nhấp. Cảm ơn!
thaspius

giải pháp đơn giản. hoạt động hoàn hảo. Tôi thích điều này hơn là tạo một chỉ thị.
Nithin Emmanuel

Thật vậy, đơn giản hơn việc phải tạo một chỉ thị. làm việc tốt cho tôi. Cảm ơn
estellechvl

3
Đơn giản cho một kịch bản sử dụng một lần. Tôi khuyên bạn nên sử dụng lệnh cho bất kỳ ai cần sử dụng mã này ở nhiều nơi trong suốt chế độ xem - đối với một lệnh, việc mở rộng chức năng, xử lý nhiều sự kiện hơn và đặc biệt là cố gắng giữ logic khỏi đánh dấu càng nhiều càng tốt khả thi. Chúc mừng!
Danny Bullis

Chiến lược này không hoạt động nếu chúng ta nhấp vào một nút, liên kết khác. Liên kết hiện tại không bị đóng
Saurabh

9

stopPropagationphải được gọi trên một đối tượng sự kiện, không phải bản thân phần tử. Đây là một ví dụ:

compile: function (elm) {
    return function (scope, elm, attrs) {
        $(elm).click(function (event) {
            event.stopPropagation();
        });
    };
}

Cảm ơn. Tôi đã chỉnh sửa câu hỏi để lệnh gọi stopPropagation trên sự kiện chứ không phải phần tử. Không hoạt động. Tìm thấy điều này: "Hiện tại một số lệnh (tức là ng: click) ngừng truyền sự kiện. Điều này ngăn cản khả năng tương tác với các khuôn khổ khác dựa vào việc nắm bắt các sự kiện như vậy." - github.com/angular/angular.js/issues/259
Robert Christian,

Vì vậy, phát hiện này được sửa chữa: <a ng-click="doThing($index); $event.stopPropagation();"> x </a>
Robert Christian

1

Đây là một chỉ thị đơn giản, trừu tượng để dừng truyền sự kiện. Tôi nghĩ nó có thể hữu ích cho ai đó. Chỉ cần vượt qua trong trường hợp bạn muốn dừng lại.

<div stopProp="click"></div>

app.directive('stopProp', function () {
  return function (scope, elm, attrs) {
    elm.on(attrs.stopProp, function (event) {
        event.stopPropagation();
    });
  };
});


2
không cần phải có stop-proptrong phần tử?
Pete
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.