Як я можу зробити директиву AngularJS, щоб зупинити поширення?


76

Я намагаюся "stopPropagation", щоб запобігти закриттю спадного меню навігаційної панелі Twitter Bootstrap, коли клацне елемент (посилання) всередині li. Використання цього методу, здається, є загальним рішенням .

У Angular, здається, директива - це місце для цього? Отже я маю:

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

... але метод не належить елементу:

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

Я пов’язую директиву з

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

Будь-які пропозиції?


Ви повинні звільнити місце в тегах для javascript (або навіть jquery ).
Джозеф Сільбер

Гарна пропозиція. Зробив редагування.
Роберт Крістіан

Причиною того, event.stopPropagation()що ваш код не працює, є те, що AngularJS та jQuery мають два окремі цикли подій . Це одна з причин, чому взагалі погано використовувати їх обох. Ваша подія кліку, визначена за ngClickдопомогою Angular, але ви намагаєтеся використовувати jQuery, щоб зупинити розповсюдження події.
Джош Девід Міллер

Відповіді:


156

Я використав такий спосіб: Створив директиву:

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

що можна використовувати таким чином:

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

Це більш загальний спосіб зупинити поширення будь-яких подій.


До речі, чи можете Ви докладніше описати ключове слово restrict? Не знайти хорошого ресурсу для того, що це саме означає.
Роберт Крістіан

Звичайно! docs.angularjs.org/guide/directive "Об'єкт визначення директиви": обмеження - Рядок підмножини EACM, який обмежує директиву певним стилем декларації директиви. Якщо пропущені директиви дозволені лише щодо атрибутів.
Валентин Шибанов

Це цікавий підхід ... мені це подобається. Дякую!
incutonez

1
Те саме рішення для .prefentDefault () в IE7, щоб запобігти перезавантаженню сторінок. Чудове рішення!
Малкус

1
О, Господи, я люблю директиви
Deminetix

123

"В даний час деякі директиви (тобто ng: click) зупиняють розповсюдження подій. Це перешкоджає взаємодії з іншими фреймворками, які покладаються на фіксацію таких подій." - посилання

... і зміг виправити без директиви, а просто зробивши:

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

4
Це було ідеально. У мене був випадаючий список із формою. Я додав ng-click = "$ event.stopPropagation ()" до div навколо форми, і це виправило випадаючий список, який не зникав при натисканні на введення форми. Дякую!
таспій

просте рішення. працював ідеально. Я віддав би перевагу цьому, а не створював директиву.
Нітін Еммануель

Дійсно, простіше, ніж створювати директиву. прекрасно працює для мене. Дякую
estellechvl

3
Просто для сценарію одноразового використання. Я б рекомендував використовувати директиву кожному, кому потрібно використовувати цей код у кількох місцях у всьому поданні - з одного боку, простіше розширити функціональність, обробляти більше подій, і особливо намагатися утримувати логіку від розмітки стільки, скільки можливо. На здоров’я!
Денні Булліс

Ця стратегія не працює, якщо ми натискаємо іншу кнопку, посилання. Поточне посилання не закривається
Саураб

9

stopPropagationмає викликатися для об'єкта події, а не самого елемента. Ось приклад:

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

Дякую. Я відредагував питання так, що директива викликає stopPropagation на подію, а не на елемент. Не працював. Знайшов це: "В даний час деякі директиви (тобто ng: click) зупиняють розповсюдження подій. Це перешкоджає сумісності з іншими фреймворками, які покладаються на фіксацію таких подій." - github.com/angular/angular.js/issues/259
Роберт Крістіан

Тож виявилося, що це виправлення: <a ng-click="doThing($index); $event.stopPropagation();"> x </a>
Роберт Крістіан,

1

Ось проста абстрактна директива про зупинення розповсюдження подій. Я думаю, це може бути корисно комусь. Просто перейдіть у тому випадку, якщо ви хочете зупинитися.

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

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


2
хіба це не повинно бути stop-propв елементі?
Піт,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.