Não consigo encontrar uma maneira de chamar uma função no escopo pai de uma diretiva sem usar o escopo isolado. Eu sei que se eu usar o escopo isolado, posso apenas usar "&" no isolado para acessar a função no escopo pai, mas usar o escopo isolado quando não é necessário tem consequências. Considere o seguinte HTML:
<button ng-hide="hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>
Neste exemplo simples, quero mostrar uma caixa de diálogo de confirmação de JavaScript e apenas chamar doIt () se clicar em "OK" na caixa de diálogo de confirmação. Isso é simples usando um escopo isolado. A diretiva ficaria assim:
.directive('confirm', function () {
return {
restrict: 'A',
scope: {
confirm: '@',
confirmAction: '&'
},
link: function (scope, element, attrs) {
element.bind('click', function (e) {
if (confirm(scope.confirm)) {
scope.confirmAction();
}
});
}
};
})
Mas o problema é que, como estou usando escopo isolado, ng-hide no exemplo acima não é mais executado no escopo pai , mas sim no escopo isolado (uma vez que usar um escopo isolado em qualquer diretiva faz com que todas as diretivas nesse elemento usar o escopo isolado). Aqui está um jsFiddle do exemplo acima em que ng-hide não está funcionando. (Observe que neste violino, o botão deve se ocultar quando você digita "sim" na caixa de entrada.)
A alternativa seria NÃO utilizar um âmbito de aplicação isolado , o que de facto é o que pretendo aqui, uma vez que não há necessidade de isolar o âmbito desta directiva. O único problema que tenho é como chamo um método no escopo pai se não o transmito no escopo isolado ?
Aqui está um jsfiddle onde NÃO estou usando escopo isolado e o ng-hide está funcionando bem, mas, é claro, a chamada para confirmAction () não funciona e não sei como fazê-la funcionar.
Observe que a resposta que realmente estou procurando é como chamar funções no escopo externo SEM usar um escopo isolado. E não estou interessado em fazer com que esse diálogo de confirmação funcione de outra maneira, porque o objetivo desta questão é descobrir como fazer chamadas para o escopo externo e ainda ser capaz de fazer outras diretivas funcionarem contra o escopo pai.
Como alternativa, eu estaria interessado em ouvir sobre soluções que usam um escopo isolado se outras diretivas ainda funcionarem contra o escopo pai , mas não acho que isso seja possível.
fonte
Respostas:
Como a diretiva está apenas chamando uma função (e não tentando definir um valor em uma propriedade), você pode usar $ eval em vez de $ parse (com um escopo não isolado):
Ou melhor, simplesmente use $ apply , que $ eval () uate seu argumento contra o escopo:
Violino
fonte
confirm-action="doIt(arg1)"
, e, em seguida, definirscope.arg1
antes de chamar $ eval. No entanto, provavelmente seria mais limpo usar $ parse: stackoverflow.com/a/16200618/215945scope.$eval(attrs.confirmAction({arg1: 'blah'})
não funcionará. Você precisaria usar $ parse com essa sintaxe.Você deseja usar o serviço $ parse no AngularJS.
Então, para seu exemplo:
Existe uma pegadinha a ver com definir uma propriedade usando $ parse, mas vou deixar você cruzar essa ponte quando chegar a ela.
fonte
scope:true
) funciona porque a diretiva não criará um novo escopo e, portanto, ascope
propriedade que você faz referência nalink
função tem exatamente o mesmo escopo que o escopo 'pai' anterior.Chame explicitamente
hideButton
o escopo pai.Aqui está o violino: http://jsfiddle.net/pXej2/5/
E aqui está o HTML atualizado:
fonte
Em primeiro lugar, um pequeno ponto: neste caso, o âmbito do controlador externo não é o âmbito principal do âmbito da diretiva; âmbito do controlador externo é o âmbito da directiva. Em outras palavras, os nomes das variáveis usados na diretiva serão pesquisados diretamente no escopo do controlador.
Em seguida, escrever
attrs.confirmAction()
não funciona porqueattrs.confirmAction
para este botão,é a string
"doIt()"
e você não pode chamar uma string, por exemplo"doIt()"()
.Sua pergunta realmente é:
Em JavaScript, você geralmente chama funções usando notação de ponto, como este:
Mas você também pode usar a notação de matriz:
Observe como o valor do índice é uma string . Portanto, em sua diretiva, você pode simplesmente fazer isso:
fonte