Entendo que o AngularJS executa algum código duas vezes, às vezes até mais, como $watch
eventos, verificando constantemente os estados do modelo etc.
No entanto meu código:
function MyController($scope, User, local) {
var $scope.User = local.get(); // Get locally save user data
User.get({ id: $scope.User._id.$oid }, function(user) {
$scope.User = new User(user);
local.save($scope.User);
});
//...
É executado duas vezes, inserindo 2 registros no meu banco de dados. Eu claramente ainda estou aprendendo, já que estou batendo minha cabeça contra isso há séculos!
ng-app
e com autoinicialização). Verifique também se você conectou seu controlador a vários elementos (com ng-controller).Respostas:
O roteador de aplicativos especificou a navegação da seguinte
MyController
maneira:Mas eu também tive isso em
home.html
:Isso digeriu o controlador duas vezes. A remoção do
data-ng-controller
atributo do HTML resolveu o problema. Como alternativa, acontroller:
propriedade poderia ter sido removida da diretiva de roteamento.Esse problema também aparece ao usar a navegação com guias. Por exemplo,
app.js
pode conter:O HTML correspondente da guia de relatórios pode se parecer com:
Isso também resultará na execução do controlador duas vezes.
fonte
<div ng-view>...
para<div class="ng-view">...
, esse problema parou para mim. Eu nunca me deparei com esse comportamento antes, mas talvez alguém também tenha isso.Quando você usa ngRoute com a
ng-view
diretiva, o controlador é anexado a esse elemento dom por padrão (ou ui-view se você usar ui-router). Portanto, você não precisará anexá-lo novamente no modelo.fonte
Acabei de passar por isso, mas o problema era diferente da resposta aceita. Estou realmente deixando isso aqui para o meu eu futuro, para incluir as etapas pelas quais passei para corrigi-lo.
ng-ifs
ng-view
chamadas de quebra de linha desnecessárias (deixei acidentalmente umang-view
que estava encerrando a minha atualng-view
. Isso resultou em três chamadas para meus controladores.)turbolinks
gema do seuapplication.js
arquivo. Eu perdi um dia inteiro para descobrir isso. Encontre a resposta aqui .fonte
turbolinks
gema do seuapplication.js
arquivo. Isso me deixou louco, desperdiçado o dia inteiro para descobrir isso. Dor de verdade. A resposta encontrada aqui éSó quero adicionar mais um caso quando o controlador puder iniciar duas vezes (isso é real para angular.js 1.3.1):
Nesse caso, $ route.current já estará definido quando o ng-view for iniciado. Isso causa dupla inicialização.
Para corrigi-lo, basta alterar ng-if para ng-show / ng-hide e tudo funcionará bem.
fonte
ui-view
duas vezes que chamou o controlador duas vezes.Gostaria de adicionar como referência:
A execução dupla do código do controlador também pode ser causada pela referência ao controlador em uma diretiva que também é executada na página.
por exemplo
Quando você também possui ng-controller = "myController" no seu HTML
fonte
Ao usar o angular-ui-router com o Angular 1.3+, houve um problema sobre as visualizações de renderização duas vezes na transição de rota . Isso resultou na execução de controladores duas vezes também. Nenhuma das soluções propostas funcionou para mim.
No entanto, a atualização
angular-ui-router
de 0.2.11 para 0.2.13 resolveu o problema para mim.fonte
Rasguei meu aplicativo e todas as suas dependências em bits sobre esse problema (detalhes aqui: aplicativo AngularJS iniciando duas vezes (tentei as soluções usuais ..) )
E no final, tudo foi culpa do plugin Batarang Chrome.
Resolução nesta resposta :
Eu recomendo fortemente que a primeira coisa na lista de qualquer pessoa seja desativá-la pela postagem antes de alterar o código.
fonte
Se você souber que seu controlador está executando acidentalmente mais de uma vez, tente pesquisar nos arquivos o nome do controlador incorreto, por exemplo: search: MyController em todos os arquivos. Provavelmente ele foi copiado e colado em algum outro arquivo html / js e você esqueceu de alterá-lo quando começou a desenvolver ou usar esses parciais / controladores. Fonte: Eu cometi este erro
fonte
Eu tive o mesmo problema, em um aplicativo simples (sem roteamento e uma referência ng-controller simples) e o construtor do meu controlador foi executado duas vezes. Por fim, descobri que meu problema era a seguinte declaração para autoinicializar automaticamente meu aplicativo AngularJS na visualização Razor
Também o iniciei manualmente usando angular.bootstrap, ou seja,
então remover um deles funcionou para mim.
fonte
Em alguns casos, sua diretiva é executada duas vezes quando você simplesmente não corrige a diretiva de fechamento dessa maneira:
<my-directive>Some content<my-directive>
Isso executará sua diretiva duas vezes. Também há outro caso frequente em que sua diretiva é executada duas vezes:
verifique se você não está incluindo sua diretiva no seu
index.html
DUAS VEZES !fonte
Estando ciscando a cabeça sobre esse problema com o AngularJS 1.4 rc build, percebi que nenhuma das respostas acima era aplicável, pois ela se originou da nova biblioteca de roteadores do Angular 1.4 e do Angular 2 no momento da redação deste documento. Portanto, deixo aqui uma nota para qualquer pessoa que possa estar usando a nova biblioteca de rotas Angular.
Basicamente, se uma página html contiver uma
ng-viewport
diretiva para carregar partes do seu aplicativo, clicar em um hiperlink especificado emng-link
faria com que o controlador de destino do componente associado fosse carregado duas vezes. A diferença sutil é que, se o navegador já carregou o controlador de destino, clicar novamente no mesmo hiperlink chamaria o controlador apenas uma vez.Ainda não encontrei uma solução viável, embora eu acredite que esse comportamento seja consistente com a observação levantada pelo shaunxu , e espero que esse problema seja resolvido na construção futura da nova biblioteca de rotas e nas versões do AngularJS 1.4.
fonte
No meu caso, encontrei duas visualizações usando o mesmo controlador.
fonte
O problema que estou encontrando pode ser tangencial, mas como o Google me levou a essa pergunta, isso pode ser apropriado. O problema é horrível para mim ao usar o roteador da interface do usuário, mas apenas quando tento atualizar a página com o botão de atualização do navegador. O aplicativo usa o roteador da interface do usuário com um estado abstrato pai e os estados filho fora do pai. Na
run()
função do aplicativo , há um$state.go('...child-state...')
comando. O estado pai usa aresolve
e, a princípio, pensei que talvez um controlador filho esteja executando duas vezes.Tudo está bem antes que o URL tenha o hash anexado.
www.someoldwebaddress.org
Depois que o URL for modificado pelo roteador da interface do usuário,
www.someoldwebaddress.org#/childstate
... e, em seguida, quando atualizo a página com o botão de atualização do navegador , o
$stateChangeStart
acionador é acionado duas vezes e cada vez aponta para ochildstate
.O
resolve
estado pai é o que está disparando duas vezes.Talvez isso seja uma farsa; de qualquer maneira, isso parece eliminar o problema para mim: na área do código onde
$stateProvider
é chamado pela primeira vez , verifique primeiro se o window.location.hash é uma string vazia. Se for, tudo é bom; caso contrário, defina o window.location.hash para uma sequência vazia. Então parece que as$state
únicas tentativas de ir a algum lugar uma vez e não duas.Além disso, se você não deseja confiar no padrão do aplicativo
run
estate.go(...)
, pode tentar capturar o valor do hash e usá-lo para determinar o estado filho em que estava antes da atualização da página e adicionar uma condição à área em seu código onde você define ostate.go(...)
.fonte
No meu caso, foi por causa do padrão de URL que usei
meu url era como / ui / project /: parameter1 /: parameter2.
Eu não precisava do paramerter2 em todos os casos de mudança de estado. Nos casos em que não precisei do segundo parâmetro, meu URL seria como / ui / project /: parameter1 /. E assim, sempre que eu tinha uma alteração de estado, meu controlador era atualizado duas vezes.
A solução foi definir o parâmetro2 como uma sequência vazia e fazer a mudança de estado.
fonte
Eu tive essa inicialização dupla por um motivo diferente. Para algumas transições de rota no meu aplicativo, eu queria forçar a rolagem até o topo da página (por exemplo, nos resultados de pesquisa paginados ... clicar em Avançar deve levá-lo ao topo da página 2).
Fiz isso adicionando um ouvinte ao
$rootScope
$on
$viewContentLoaded
qual (com base em determinadas condições) executouInadvertidamente, isso estava fazendo com que minhas rotas fossem reavaliadas e os controladores fossem reinicializados
fonte
Meu problema foi atualizar os parâmetros de pesquisa dessa forma
$location.search('param', key);
Você pode ler mais sobre isso aqui
controlador sendo chamado duas vezes devido à adição de parâmetros no URL
fonte
No meu caso, renomear o controlador com um nome diferente resolveu o problema.
Houve um conflito de nomes de controladores com o módulo " angular-ui-tree ": renomeei meu controlador de "CatalogerTreeController" para " TreeController " e esse controlador começa a ser iniciado duas vezes na página em que a diretiva " ui-tree " foi usada porque Esta diretiva usa o controlador chamado " TreeController ".
fonte
Para aqueles que usam a sintaxe ControllerAs, basta declarar o rótulo do controlador no $ routeprovider da seguinte maneira:
ou
Depois de declarar o $ routeprovider, não forneça o controlador como na exibição. Em vez disso, use o rótulo na exibição.
fonte
Eu tive o mesmo problema e, depois de tentar todas as respostas, finalmente descobri que tinha uma diretiva na minha opinião que estava vinculada ao mesmo controlador.
Após remover a diretiva, o controlador parou de ser chamado duas vezes. Agora, minha pergunta é: como usar essa diretiva vinculada ao escopo do controlador sem esse problema?
fonte
Acabei de resolver o meu, o que foi realmente muito decepcionante. É um aplicativo híbrido iônico, usei o ui-router v0.2.13. No meu caso, há um leitor de epub (usando epub.js) que relatava continuamente "nenhum documento encontrado" depois que navegava para a biblioteca de livros e selecionava qualquer outro livro. Quando recarreguei, o livro do navegador estava sendo renderizado perfeitamente, mas quando selecionei outro livro, o mesmo problema foi novamente.
Minha resolução foi muito simples. I acabou de remover
reload:true
a partir$state.go("app.reader", { fileName: fn, reload: true });
da minhaLibraryController
fonte
Eu tenho o mesmo problema
[email protected]
, e porque a barra extra no final da rota regex:para
e funciona corretamente.
fonte
Apenas adicionando meu caso aqui também:
Eu estava usando angular-ui-router com
$state.go('new_state', {foo: "foo@bar"})
Uma vez eu adicionei encodeURIComponent ao parâmetro, o problema se foi:
$state.go('new_state', {foo: encodeURIComponent("foo@bar")})
.O que aconteceu? O caractere "@" no valor do parâmetro não é permitido nos URLs. Como conseqüência, o angular-ui-router criou meu controlador duas vezes: durante a primeira criação, passou o "foo @ bar" original, durante a segunda criação passou a versão codificada "foo% 40bar". Depois de codificar explicitamente o parâmetro, como mostrado acima, o problema desapareceu.
fonte
Eu descobri que o meu está sendo chamado duas vezes é porque eu estava chamando o método duas vezes no meu html.
A seção destacada estava fazendo com que findX () fosse chamado duas vezes. Espero que ajude alguém.
fonte