Como posso controlar a ordem dos comportamentos do Drupal.be?

9

Quero que o código JavaScript do módulo X seja executado somente depois que o código do módulo Y for executado. Qual é a melhor forma de fazer isso?

cam8001
fonte

Respostas:

5

O código JavaScript usado pelo Drupal 7 é o seguinte:

Drupal.attachBehaviors = function (context, settings) {
  context = context || document;
  settings = settings || Drupal.settings;
  // Execute all of them.
  $.each(Drupal.behaviors, function () {
    if ($.isFunction(this.attach)) {
      this.attach(context, settings);
    }
  });
};

Drupal 6 usa código semelhante:

Drupal.attachBehaviors = function(context) {
  context = context || document;
  if (Drupal.jsEnabled) {
    // Execute all of them.
    jQuery.each(Drupal.behaviors, function() {
      this(context);
    });
  }
};

Se o JavaScript garantir que as propriedades do objeto / matriz sempre sejam atravessadas na mesma ordem em que foram adicionadas, os valores serão transferidos jQuery.each()para a função usada como segundo parâmetro na mesma ordem em que são inseridos na matriz passada como primeiro parâmetro.
Isso significa que o primeiro comportamento inserido Drupal.behaviorsé executado primeiro.
Nesse caso, para permitir que os comportamentos definidos pelo seu módulo sejam executados primeiro, você pode usar um peso menor para isso. Se você deseja que eles sejam executados antes dos outros, o peso do módulo deve ser definido como -50; outros valores também podem funcionar. Se você estiver usando o Drupal 7, drupal_add_js ()permite associar um peso ao código JavaScript; O código JavaScript com menor peso aparece primeiro na saída HTML. Isso não é possível com o Drupal 6, pensou.

O JavaScript não garante que as propriedades sejam percorridas na mesma ordem em que foram adicionadas. Isso significa que diferentes implementações de JavaScript apresentariam as mesmas propriedades usando uma ordem diferente; isso também significa que a mesma ordem pode mudar em versões diferentes do mesmo navegador.

kiamlaluno
fonte
Certa vez, encontrei uma página que listava o peso usado por alguns módulos. Não lembro o URL dessa página e se a página incluía apenas módulos específicos ou era exaustiva. Se eu encontrar essa página, relatarei aqui o link.
kiamlaluno
11
Você sempre pode apenas verificar a tabela do sistema - tryselect name, weight from system where type = 'module' order by weight ASC, name
cam8001 31/11
Infelizmente, preciso que o PHP do meu módulo (mymodule) seja executado antes do PHP do outro módulo (vertical_tabs), mas o JS do meu módulo seja executado após o js do vertical_tab. Existe uma maneira puramente baseada em javascript para ponderar comportamentos?
cam8001
@ cam8001: Eu sei disso, mas isso significa que você deve instalar todos os módulos, para saber o menor peso usado por um módulo. A página encontrada listou os pesos dos módulos e pode ser útil quando você precisar saber qual peso deve atribuir ao seu módulo para ser executado antes de cada módulo. Eu sei, você poderia simplesmente usar um peso extremamente leve, mas usaria um peso mais leve do que o necessário.
kiamlaluno
@ cam8001: Nesse caso, não há como realizar o que você está tentando fazer, exceto alterar a ordem dos objetos contidos Drupal.behaviors; como relatei, $.each(Drupal.behaviors)lista os objetos na mesma ordem em que são inseridos, sem basear-se no identificador.
kiamlaluno
5

Use o módulo Comportamentos .
(Faça alguns testes antes de usá-lo em um site de produção)

O módulo permite anexar pesos aos comportamentos e, em seguida, sequestra / substitui drupal.attachBehaviorspor uma implementação personalizada, que respeita os pesos.


Por que não o peso do módulo, como sugerido na outra resposta?

  • O peso do módulo é uma ferramenta bastante pesada. Isso se aplica a todas as implementações de ganchos (php) e comportamentos (js) do módulo, enquanto estamos interessados ​​apenas em um único comportamento.
  • a ordem das propriedades em um objeto js não é garantida pela especificação (embora seja implementada conforme o esperado em quase todos os navegadores).

Consulte
A ordem dos campos em um objeto javascript é previsível ao fazer um loop entre eles? e
Elementos de ordem - para (… in…) loop em javascript .

Don Quixote
fonte
@kiam, Se eu fizer deste um módulo "peso do comportamento" ("bewgt") no drupal.org, você entraria como um co-mantenedor? Provavelmente será um módulo bastante pequeno, mas provavelmente melhor do que deixá-lo enviado com outra coisa. Eu tenho uma implementação de exemplo localmente para D6, parece funcionar.
Donquixote 7/10
apenas feito isso .. você ainda está convidado :)
Donquixote
drupal.org/node/1302126 - Espero que este será em núcleo em D8 :)
Donquixote
Seria um módulo interessante, mas primeiro tenho que atualizar o código de alguns dos meus módulos, para os quais não escrevi uma linha de código desde tempos antigos. Depois disso, eu poderia estar livre para co-desenvolver um novo módulo.
kiamlaluno
Apenas dizendo, as pessoas estão pedindo casos de uso. drupal.org/node/1302126#comment-5911632
Donquixote
0

Para Drupal 6 -

Uma solução simples, se isso não precisar ser portátil, é colocar o JS que você deseja executar por último no arquivo template.php do tema. As chamadas drupal_add_js do tema são sempre chamadas após os módulos.

Se precisar ser portátil, a solução "mais limpa" no drupal 6 é adicionar um novo módulo com peso diferente do seu módulo com o php. Você pode até ter os dois módulos na mesma pasta, tornar o primeiro módulo dependente do primeiro e ajustar os pesos nos ganchos de instalação / atualização. Nada disso é necessário, apenas facilita a instalação.

mirzu
fonte