Javascript complexo conjunto “redução elemento” - a construção de uma tabela HTML com base em elementos da matriz

StackOverflow https://stackoverflow.com/questions/1419811

Pergunta

Eu tenho um projeto que requer o seguinte.

Quatro matrizes será declarado no código como tal:

var ROW1 = ['module1'];
var ROW2 = ['module2', 'module3'];
var ROW3 = ['module4', 'module5', 'module6'];
var ROW4 = ['module7', 'module8'];

Cada elemento dessas matrizes representa um módulo em um configurável HTML widget. Com base em que elementos são especificados em cada matriz, o código vai construir um HTML que representa estes "módulos" - cada matriz "ROWx" será uma linha da tabela (), e cada módulo será uma célula da tabela () na tabela.

ROW1 pode estar vazio (caso em que ele não será incluído no HTML) ou ter um módulo, "module1."

ROW2, row3, ROW4 e cada um pode ter entre 0 e 3 módulos (nenhum de module2 - module8, em qualquer ordem).

Usando o exemplo matrizes acima, eu programaticamente gerar uma tabela HTML assim:

<table>
  <tr id="row1">
    <td colspan="6">[module1]</td>
  </tr>
  <tr id="row2">
    <td colspan="3">[module2]</td>
    <td colspan="3">[module3]</td>
  </tr>
  <tr id="row3">
    <td colspan="2">[module4]</td>
    <td colspan="2">[module5]</td>
    <td colspan="2">[module6]</td>
  </tr>
  <tr id="row4">
    <td colspan="3">[module7]</td>
    <td colspan="3">[module8]</td>
  </tr>
</table>

(Os colspans estão ali apenas para preservar a disposição da tabela adequada; 6 é o menor múltiplo comum entre 1, 2, e 3.)

O problema é que o conteúdo para esses módulos é preenchida dinamicamente (I obtê-lo de uma chamada de AJAX para uma URL que retorna um objeto JSON), eo conteúdo não está sempre disponível para cada módulo. Em vez de criar uma célula vazia () para um módulo sem conteúdo, que deseja remover essa célula completamente a partir do layout, agindo como nunca foi na configuração original (isto é, as matrizes no topo).

Eu já passei muito tempo código criando que abstrai a criação do módulo - ele cria um "shell" HTML de layout com base em quantos módulos estão em cada linha, e em seguida, acrescenta o conteúdo para a célula tabela apropriada com base no qual módulo deve estar lá. Eu gostaria de ser capaz de continuar usando esse código, então eu acho que a melhor maneira de fazer isso é ir através de cada elemento nas matrizes antes de construir o "shell", e se eu não tiver conteúdo, remover esse elemento a partir da matriz. Então eu posso usar a matriz recém-modificado para construir o "shell" de costume - Estou basicamente apenas processá-lo com antecedência para verificar se há conteúdo em cada módulo, e se nenhum estiver disponível, agindo como esse módulo nunca foi definida na matriz inicial (removendo-o na nova matriz e, em seguida, usar isso para construir o "shell").

Por exemplo, digamos que a configuração é configurado como tal:

var ROW1 = ['module1'];
var ROW2 = ['module4', 'module2'];
var ROW3 = ['module5'];
var ROW4 = ['module7', 'module3', 'module8'];

Eu quero passar por cada elemento em cada matriz e verificar se há conteúdo disponível no módulo. Vamos dizer que não há nenhum conteúdo disponível para "module3" e "module5." Quero, em seguida, acabar com essas matrizes:

var ROW1 = ['module1'];
var ROW2 = ['module4', 'module2'];
var ROW3 = ['module7', 'module8'];

Por favor, note o que aconteceu com as linhas - uma vez que "module5" foi removido, os elementos da matriz ROW4 foram deslocados para row3 e ROW4 foi então excluído. Além disso, no novo row3 (anteriormente ROW4), "module3" foi removido, deslizando "module8" a partir da posição [2] em posição [1].

Assim:

  • Para quaisquer linhas que têm um ou mais elementos remanescentes após a remoção de módulos que não têm qualquer conteúdo, eu gostaria de manter a linha intacta, mesmo com apenas um módulo.
  • Para quaisquer linhas que acabam sem elementos restantes, eu gostaria de mudar cada linha sucessiva "up" um, para a matriz anterior, basicamente, puxando uma fila fora e mudando os inferiores para cima. O HTML a partir deste exemplo ficaria assim:

ANTES (tal como solicitado pela configuração):

<table>
  <tr id="row1">
    <td colspan="6">[module1]</td>
  </tr>
  <tr id="row2">
    <td colspan="3">[module4]</td>
    <td colspan="3">[module2]</td>
  </tr>
  <tr id="row3">
    <td colspan="6">[module5]</td>
  </tr>
  <tr id="row4">
    <td colspan="2">[module7]</td>
    <td colspan="2">[module3]</td>
    <td colspan="2">[module8]</td>
  </tr>
</table>

DEPOIS (com base no qual o conteúdo que está realmente disponível)

<table>
  <tr id="row1">
    <td colspan="6">[module1]</td>
  </tr>
  <tr id="row2">
    <td colspan="3">[module4]</td>
    <td colspan="3">[module2]</td>
  </tr>
  <tr id="row3">
    <td colspan="3">[module7]</td>
    <td colspan="3">[module8]</td>
  </tr>
</table>

Lembre-se que ROW1 é um caso especial, na medida em que não afeta outras linhas. Se o conteúdo está disponível para "module1" (o único módulo que pode ir em ROW1), então ROW1 deve existir intocado. Se nenhum conteúdo está disponível, então ROW1 pode ser excluído, mas ainda deixando ROW2, row3 e ROW4 como está (ou seja, não transferindo-os cada uma linha). Eu realmente só precisa de uma solução para lidar com ROW2, row3 e ROW4, já que a lógica para ROW1 é bastante simples.

Eu sou um iniciante / intermediário programador JavaScript, e não têm muita experiência com matrizes. Eu tenho trabalhado neste ligado e desligado durante horas, mas simplesmente não fazer taxal que o que eu estou chegando com um método robusto ou elegante / compacto.

Se nenhum gurus JavaScript podem compartilhar uma solução para isso, eu gostaria muito que isso! Agradece a um grupo.

Foi útil?

Solução

Em primeiro lugar, armazenar as linhas em uma matriz, bem como, o seu ROW1 -. ROW4 estão indo dar-lhe dores de cabeça

var ROWS = [
 ['module1'],
 ['module4', 'module2'],
 ['module5'],
 ['module7', 'module3', 'module8']
];

Você também quer uma maneira de remover um elemento. .splice() é construído em matrizes, e funciona muito bem para remover elementos.

// lets clear out our disabled modules

var disabledModules = ['module3', 'module5'];

// quick sample function - yours might check for empty content or whatever else...
function isDisabled(module) {  
  for (var i=0, test; test=disabledModules[i]; i++) {
    if (test === module) return true;
  }
  return false;
}

for(var i=0,row; row=ROWS[i]; i++) {
  for (var j=0,module; module=row[j]; j++) {
    // is this module in our disabled modules list?

    if (isDisabled(module)) { // the module is disabled
      row.splice(j,1);
      j--; // so we recheck this point in the array
    }
  }
  if (row.length < 1) {
    // all items were deleted
    ROWS.splice(i,1);
    i--; // so we recheck this point..
  }
}

// ROWS === [["module1"], ["module4", "module2"], ["module7", "module8"]]

O seu comentário questionado sobre a para a sintaxe de loop utilizado. É uma maneira muito rápida para percorrer as matrizes que você sabe que não vai ter valores "falsas". Quebrando um aparte e ligar log detalhado:

 for(
  // Part 1 of for loop: Setup, create two variables, i=0, and row.
  var i=0,row; 
  // Part 2: The test - when false, loop will exit, gets executed pre-loop every time
  // Assignment operator returns the value assigned, so row=ROWS[i] will be undefined
  // (false) when we reach then end of the array.
  row=ROWS[i]; 
  // Part 3: Post loop - increment i
  i++) {

Os perigos de se utilizar este método de fazer existir no entanto, se a sua uma matriz de números, por exemplo, e um desses números é 0, o ciclo irá sair cedo. A alternativa seria escrever:

for(var i=0; i<ROWS.length; i++) { 
  var row = ROWS[i];
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top