Como acionar o ngClick de maneira programática

101

Quero acionar ng-clickum elemento em tempo de execução como:

_ele.click();

OU

_ele.trigger('click', function());

Como isso pode ser feito?

mulla.azzi
fonte
4
Não, quero saber o mecanismo pelo qual posso disparar o ng-click manualmente.
mulla.azzi

Respostas:

182

A sintaxe é a seguinte:

function clickOnUpload() {
  $timeout(function() {
    angular.element('#myselector').triggerHandler('click');
  });
};

// Using Angular Extend
angular.extend($scope, {
  clickOnUpload: clickOnUpload
});

// OR Using scope directly
$scope.clickOnUpload = clickOnUpload;

Mais informações sobre a forma de extensão angular aqui .

Se você estiver usando versões antigas do angular , deve usar trigger em vez de triggerHandler .

Se precisar aplicar a propagação de parada, você pode usar este método da seguinte maneira:

<a id="myselector" ng-click="clickOnUpload(); $event.stopPropagation();">
  Something
</a>
clopez
fonte
4
qual versão do angular você está usando. triggerHandler parece funcionar bem em 1.2.1: jsfiddle.net/t34z7
Blago
13
explique por que $ (elem) .click () não funciona com Angular?
Sergii Shevchyk
11
Se você está limitado ao jqLite e não pode usar um seletor, faça o seguinte: angular.element (document.querySelector ('# mySelector')). Trigger ('click');
Daniel Nalbach
3
@DanielNalbach nas versões Angular 1.2+ atuais (e não tão atuais), você deve usar em triggerHandlervez detrigger
yorch
1
Não tenho certeza se isso ainda funciona ... angularjs 1.6 parece não estar funcionando com o jquery completo
George Mauer
83
angular.element(domElement).triggerHandler('click');

EDIT: Parece que você tem que sair do ciclo atual de $ apply (). Uma maneira de fazer isso é usando $ timeout ():

$timeout(function() {
    angular.element(domElement).triggerHandler('click');
}, 0);

Veja violino: http://jsfiddle.net/t34z7/

Blago
fonte
2
mesmo isso não está funcionando, é o seguinte erro de lançamento Erro: [$ rootScope: inprog] errors.angularjs.org/1.2.14/$rootScope/inprog?p0=%24apply at Error (nativo)
mulla.azzi
8
Você provavelmente deseja usar o Angular em $timeoutvez de setTimeout, pois $timeoutele executará um $applyciclo para você, se necessário. Ele também torna seu código mais testável, pois o ngMock oferece controle total sobre quando os $timeouts são executados. docs.angularjs.org/api/ng/service/$timeout
WildlyInaccurate
2
Na verdade, isso deve ser feito $timeout(fn, 0, false);para que não invoque $ apply, não é?
Martin Probst
2
Esta deve ser a resposta aceita. triggerHandler funciona. o acionador não funciona na v1.2.25
Howie,
4
@deadManN $timeouté um serviço e, como tal, precisa ser injetado na dependência antes de poder usá-lo docs.angularjs.org/api/ng/service/$timeout
WildlyInaccurate
19

Esta solução a seguir funciona para mim:

angular.element(document.querySelector('#myselector')).click();

ao invés de :

angular.element('#myselector').triggerHandler('click');
jpmottin
fonte
@DotKu Talvez você já esteja em uma função $ scope como quando você usa em uma função $ timeout? Em outras palavras, você não pode chamar um $ scope. $ Apply () em um $ scope. $ Apply () ... Espero que isso ajude você.
jpmottin
@jpmottin Eu encontrei, deve ser colocado em $ timeout. Obrigado
Weijing Jay Lin
1
OMG, Angular totalmente arruinou. Por que eles não podem imitar o jQuery$('#element').click()
Jhourlad Estrella
13

Para o caso de todos verem, adicionei uma resposta duplicada adicional com uma linha importante que não interromperá a propagação do evento

$scope.clickOnUpload = function ($event) {    
    $event.stopPropagation(); // <-- this is important

    $timeout(function() {
        angular.element(domElement).trigger('click');
    }, 0);
};
Oculto
fonte
Obrigado! Isso finalmente funcionou para mim no 1.5.11 e dependência completa do jquery. $ timeout (function () {var el = document.getElementsByClassName ('fa-chevron-up'); angular.element (el) .trigger ('click');}, 0);
Florida G.
9

Usar o JavaScript simples funcionou para mim:
document.querySelector('#elementName').click();

charlchad
fonte
Sim. Funciona para mim. Obrigado.
ktaro
4

Você pode fazer como

$timeout(function() {
   angular.element('#btn2').triggerHandler('click');
});
Fizer Khan
fonte
Eu recebo este erro para esta solução em meu aplicativo ng 1.5.3: A pesquisa de elementos por meio de seletores não é compatível com jqLite.
Todd Hale
1

Amostra simples:

HTML

<div id='player'>
    <div id="my-button" ng-click="someFuntion()">Someone</div>
</div>

JavaScript

$timeout(function() {
    angular.element('#my-button').triggerHandler('click');
}, 0);

O que isso faz é procurar o botão ide executar uma ação de clique. Voila.

Fonte: https://techiedan.com/angularjs-how-to-trigger-click/

Leniel Maccaferri
fonte
0

Este código não funcionará (emite um erro quando clicado):

$timeout(function() {
   angular.element('#btn2').triggerHandler('click');
});

Você precisa usar o querySelector da seguinte maneira:

$timeout(function() {
   angular.element(document.querySelector('#btn2')).triggerHandler('click');
});
Guillaume-Alexandre
fonte
0

Inclua a seguinte linha em seu método onde você deseja acionar o evento de clique

angular.element('#btn_you_want_to_click_progmaticallt').triggerHandler('click');
});
Vinayak Shedgeri
fonte