Estou procurando o padrão certo para injetar uma classe de linha de bootstrap a cada 3 colunas. Eu preciso disso porque cols não tem altura fixa (e eu não quero consertar), então quebra meu design!
Aqui está o meu código:
<div ng-repeat="product in products">
<div ng-if="$index % 3 == 0" class="row">
<div class="col-sm-4" >
...
</div>
</div>
</div>
Mas ele exibe apenas um produto em cada linha. O que eu quero como resultado final é:
<div class="row">
<div class="col-sm4"> ... </div>
<div class="col-sm4"> ... </div>
<div class="col-sm4"> ... </div>
</div>
<div class="row">
<div class="col-sm4"> ... </div>
<div class="col-sm4"> ... </div>
<div class="col-sm4"> ... </div>
</div>
Posso conseguir isso apenas com o padrão ng-repeat (sem diretiva ou controlador)? Os documentos apresentam ng-repeat-start e ng-repeat-end, mas não consigo descobrir como usá-los neste caso de uso! Eu sinto que isso é algo que frequentemente usamos em modelos de bootstrap! ? obrigado
Respostas:
A resposta mais votada, embora eficaz, não é o que eu consideraria ser a forma angular, nem está usando as próprias classes de bootstrap destinadas a lidar com essa situação. Como @claies mencionou, a
.clearfix
classe é destinada a situações como essas. Na minha opinião, a implementação mais limpa é a seguinte:Essa estrutura evita a indexação confusa da matriz de produtos, permite a notação de ponto limpa e faz uso da classe clearfix para sua finalidade.
fonte
Eu sei que é um pouco tarde, mas ainda pode ajudar alguém. Eu fiz assim:
jsfiddle
fonte
ng-if="$index+1 < products.length"
eng-if="$index+2 < products.length"
Ok, esta solução é muito mais simples do que as que já estão aqui, e permite diferentes larguras de coluna para diferentes larguras de dispositivo.
Observe que a
% 6
parte deve ser igual ao número de colunas resultantes. Portanto, se no elemento de coluna você tiver a classecol-lg-2
, haverá 6 colunas, então use... % 6
.Esta técnica (excluindo o
ng-if
) está realmente documentada aqui: Bootstrap docsfonte
Embora o que você deseja realizar possa ser útil, há outra opção que eu acredito que você pode estar negligenciando que é muito mais simples.
Você está correto, as tabelas do Bootstrap agem estranhamente quando você tem colunas que não têm altura fixa. No entanto, existe uma classe de bootstrap criada para combater esse problema e realizar redefinições responsivas .
simplesmente crie um vazio
<div class="clearfix"></div>
antes do início de cada nova linha para permitir que os flutuadores sejam redefinidos e as colunas retornem às suas posições corretas.aqui está um bootply .
fonte
flex
para fazer colunas com a mesma altura?Obrigado por suas sugestões, você me pegou no caminho certo!
Vamos para uma explicação completa:
Por padrão, AngularJS http get query retorna um objeto
Portanto, se você quiser usar a função @Ariel Array.prototype.chunk, você deve primeiro transformar o objeto em um array.
E então, para usar a função chunk em SEU CONTROLADOR, caso contrário, se usada diretamente no ng-repeat, ele levará você a um erro infdig . O controlador final parece:
E o HTML se torna:
Por outro lado, decidi retornar diretamente um array [] em vez de um objeto {} do meu arquivo JSON. Desta forma, o controlador se torna (observe a sintaxe específica isArray: true ):
HTML permanece igual ao anterior.
OTIMIZAÇÃO
A última questão em suspense é: como torná-lo 100% AngularJS sem estender o array javascript com a função chunk ... se algumas pessoas estiverem interessadas em nos mostrar se ng-repeat-start e ng-repeat-end são o caminho a seguir. . Estou curioso ;)
SOLUÇÃO DE ANDREW
Graças a @Andrew, agora sabemos que adicionar uma classe bootstrap clearfix a cada três (ou qualquer número) elemento corrige o problema de exibição da altura do bloco diferente.
Então, o HTML se torna:
E seu controlador permanece bastante suave com a função chunck removida :
fonte
Você pode fazer isso sem uma diretiva, mas não tenho certeza se é a melhor maneira. Para fazer isso, você deve criar um array de array a partir dos dados que deseja exibir na tabela e, depois disso, usar 2 ng-repeat para iterar pelo array.
para criar a matriz para exibição, use esta função como em products.chunk (3)
e então fazer algo assim usando 2 ng-repeat
fonte
Baseado na solução da Alpar, usando apenas modelos com repetição de ng anidada. Funciona com linhas cheias e parcialmente vazias:
JSFiddle
fonte
Acabei de fazer uma solução funcionando apenas em template. A solução é
O ponto está usando dados duas vezes, um é para um loop externo. As tags de span extras permanecerão, mas isso depende de como você negocia.
Se for um layout de 3 colunas, será como
Honestamente eu queria
Embora não tenha funcionado.
fonte
Apenas mais uma pequena melhoria sobre a resposta @Duncan e as outras respostas com base no elemento clearfix. Se você quiser tornar o conteúdo clicável, você precisará de um
z-index
> 0 nele ou o clearfix irá sobrepor o conteúdo e controlar o clique.Este é o exemplo que não está funcionando (você não pode ver o ponteiro do cursor e clicar não fará nada):
Embora este seja o único :
Eu adicionei
z-index: 1
para que o conteúdo aumentasse sobre o clearfix e removi o contêiner div usando em vez dissong-repeat-start
eng-repeat-end
(disponível em AngularJS 1.2) porque ele fez o z-index não funcionar.Espero que isto ajude!
Atualizar
Plunker: http://plnkr.co/edit/4w5wZj
fonte
flex
em linhas para fazer colunas com a mesma altura?eu resolvi isso usando ng-class
fonte
A melhor maneira de aplicar uma classe é usar ng-class. Ele pode ser usado para aplicar classes com base em alguma condição.
e então em seu controlador
fonte
Depois de combinar muitas respostas e sugestões aqui, esta é a minha resposta final, que funciona bem com
flex
, o que nos permite fazer colunas com altura igual, também verifica o último índice, e você não precisa repetir o HTML interno. Não usaclearfix
:A saída será algo assim:
fonte
Uma pequena modificação na solução de @alpar
jsfiddle
fonte
Isso funcionou para mim, sem emenda ou qualquer coisa necessária:
HTML
JavaScript
fonte
Born Solutions é o melhor, só preciso ajustar um pouco para atender às necessidades, eu tive diferentes soluções responsivas e mudei um pouco
fonte
Com base na resposta da Alpar, aqui está uma maneira mais generalizada de dividir uma única lista de itens em vários contêineres (linhas, colunas, baldes, qualquer que seja):
para uma lista de 10 itens, gera:
O número de recipientes pode ser rapidamente codificado em uma função de controlador:
JS (ES6)
HTML
Essa abordagem evita duplicar a marcação do item (
<span>{{item.name}}</span>
neste caso) no modelo de origem - não uma grande vitória para um período simples, mas para uma estrutura DOM mais complexa (que eu tinha), isso ajuda a manter o modelo SECO.fonte
Atualização 2019 - Bootstrap 4
Uma vez que o Bootstrap 3 usava flutuadores, é necessário que o clearfix resete a cada n (3 ou 4) colunas (
.col-*
) no.row
para evitar empacotamento desigual de colunas.Agora que o Bootstrap 4 usa o flexbox , não há mais necessidade de envolver as colunas em
.row
tags separadas ou inserir divs extras para forçar cols a envolver todos os n colunas.Você pode simplesmente repetir todas as colunas em um único
.row
contêiner.Por exemplo, 3 colunas em cada linha visual são:
Portanto, para o Bootstrap, a repetição do ng é simplesmente:
Demo: https://www.codeply.com/go/Z3IjLRsJXX
fonte
Fiz apenas usando boostrap, você deve ter muito cuidado na localização da linha e da coluna, aqui está o meu exemplo.
fonte