17

Sto provando a creare una griglia di carte Angolare-Materiale che si comporta in qualche modo come una griglia Bootstrap. Idealmente, le schede saranno a larghezza intera per le piccole dimensioni dello schermo e saliranno a due colonne in punti di interruzione più grandi.Come creare un reattivo (numero di colonne variabile) Griglia tessera angolare-materiale

Demo with 2 cards

Il problema è che A-M crea colonne per ogni carta. Non ho capito come specificare il numero di colonne per ogni punto di interruzione.

Demo with 5 cards

Ecco la base del markup che sto utilizzando, che prende il layout della carta da righe alle colonne al primo punto di interruzione:

<div ng-app layout="column" layout-gt-sm="row" class="layout-sm-column layout-row"> 
    <div flex class="flex" ng-repeat="i in [1,2,3,4,5] track by $index"> 
    <md-card> 

C'è già un similar question on SO, ma risposta accettata è insoddisfacente in quanto utilizza CSS personalizzati e le carte non hanno una larghezza del fluido. Non ho trovato altri esempi simili.

Suppongo di poter eseguire il loop di ogni due carte con Angular e creare serie impilate, ma ciò sembra inutilmente ingombrante. Devo pensare che il materiale fornisca una soluzione migliore. Inoltre, tali soluzioni lascerebbero spazi bianchi nella pagina in cui le carte variano in altezza. Il materiale sembra orientato verso un layout flessibile simile alla massoneria, e mi piacerebbe attenervisi.

Grazie.

+0

Possibile con solo css, anche con un aspetto/stile in muratura. http://designshack.net/articles/css/masonry/#bsap_1610 – g19fanatic

+0

La domanda è come farlo con materiale angolare. Ho molta esperienza con altre librerie e tecniche. Questa sembra essere una deficienza di A.M., comunque, a meno che mi manchi qualcosa. – isherwood

+0

Ho incontrato esattamente questo stesso problema e non esiste una soluzione nativa che esegua una griglia di tipo muratura per te. La reattività di AM proviene dai contenitori flexbox, non a livello di direttiva, quindi non comunicano realmente tra loro. In realtà ho creato set impilati proprio come mi hai suggerito. – staypuftman

risposta

18

È possibile utilizzare il materiale Grid-List, consente la personalizzazione delle spaziature e l'animazione delle modifiche quando la larghezza cambia.

Ho adattato il campione dal sito e aggiunto md-card nei contenuti. Assicurati di aggiungere layout-fill allo md-card. È possibile adattare facilmente il campione per il conteggio delle colonne.

http://codepen.io/anon/pen/QypjWY

Ho anche adattato il campione di 5 carte. È necessario conoscere l'altezza delle carte per utilizzare la griglia, ma è possibile ottenere facilmente l'altezza del 100% su schermi di piccole dimensioni. Puoi utilizzare i rapporti o le altezze CSS fisse per le righe e quindi è compito delle tue schede mostrare i contenuti in modo flessibile.

<md-grid-list ng-app="app" layout-fill flex 
    md-cols-sm="1" 
    md-cols-md="2" 
    md-cols-gt-md="5" 
    md-row-height-sm="100%" 
    md-row-height="600px" 
    md-gutter="8px"> 
    <md-grid-tile ng-repeat="i in [1,2,3,4,5] track by $index"> 
     <md-card layout-fill> 

http://jsfiddle.net/2afaok1n/34/

Edit:

Se siete invece alla ricerca di un qualche tipo di griglia sfalsata, allora si deve aggiungere una libreria: angular-deckgrid, essa fornisce solo il layout della griglia, tutto nel contenuto è angolare-materiale. A differenza di angular-masonry questa libreria non ha alcuna dipendenza. Se non si è preoccupati di aggiungere jQuery e simili, è possibile utilizzare anche la muratura angolare.

<div ng-app="app" ng-controller="DeckController" flex layout="column"> 
    <deckgrid class="deckgrid" flex source="data"> 
     <md-card> 

La parte importante per la disposizione della piattaforma è il CSS configuration. Con questo si configura il numero di colonne e la loro larghezza. Ho utilizzato una query multimediale per il punto di interruzione del materiale angolare sm per passare al layout a colonna singola.

.deckgrid::before { 
    content: '4 .column.column-1-4'; 
    font-size: 0; 
    visibility: hidden; 
} 

.deckgrid .column { 
    float: left; 
} 

.deckgrid .column-1-4 { 
    width: 25%; 
} 

.deckgrid .column-1-1 { 
    width: 100%; 
} 

@media screen and (max-width: 960px) { 
    .deckgrid::before { 
    content: '1 .column.column-1-1'; 
    } 
} 

http://jsfiddle.net/2afaok1n/39/

Edit 2:

Esiste anche una versione in muratura che non necessitano di jQuery e una semplice direttiva usarlo: angular-masonry-directive. Ecco un esempio, funziona in modo simile all'altro.

http://jsfiddle.net/xjnp97ye/1/

+0

Il primo esempio sembra un buon inizio, ma non sono sicuro di poter convivere con le altezze fisse. Ho semplificato la demo per i miei scopi: http://codepen.io/anon/pen/YwZwbz La seconda lascia diversi spazi bianchi tra le righe, come ho detto nella mia domanda. Probabilmente non funzionerà. – isherwood

+0

Sono affascinato dal tuo aggiornamento, ma il terzo esempio (39) non sembra mostrare un comportamento reattivo. Il quarto esempio sembra una buona opzione. – isherwood

+0

Hai ragione, il terzo è un po 'limitato. Se esegui quell'esempio con una grande larghezza e quindi riduci la larghezza, agirà in modo reattivo ma non viceversa. Funzionerà comunque come previsto su diversi dispositivi con larghezza e/o ridisegno fissi, ad es. rotazione del dispositivo ecc. La libreria analizza il blocco CSS pseudo ':: before' e deve ottenere qualcosa di sbagliato lì. – kuhnroyal

1

Se ho capito la domanda giusta, questo funziona come un fascino:

<body ng-app="app" ng-cloak> 
    <div layout="column" layout-gt-sm="row" layout-wrap> 
    <div flex="25" flex-gt-sm="50" ng-repeat="i in [1,2, 3, 4, 5] track by $index"> 
    <md-card> 
    <!-- You code--> 
    </md-card> 
    </div> 
    </div> 
</body> 

Plunker con più punti di interruzione: (ridimensionare la finestra interna, non la finestra del browser) http://plnkr.co/edit/8QPYdzLD8qzEbdz5sesE?p=preview

Il plunker è stato aggiornato per mostrare carte con altezza diversa.
Sono state create 2 direttive, quindi l'altezza massima di tutte le carte viene mantenuta in memoria e questa viene applicata a tutte le carte.

+0

Grazie, ma non riesco a farlo visualizzare più di una modifica del punto di interruzione. Puoi migliorare la demo per mostrare almeno 3? – isherwood

+0

Vedere l'aggiornamento. Prego – gr3g

+0

Ho biforcato una versione con contenuti diversi. Come puoi vedere, non funziona bene. Le carte corrono insieme e tagliano il contenuto. Pensieri? http://plnkr.co/edit/VNyWOpCocKGfY0qX2IjK?p=preview – isherwood

1
<div ng-repeat="i in [1,2, 3, 4, 5] track by $index" flex-xs="100" flex-sm="50" flex-md="50" flex="33"> 
<md-card> 

    <md-card-title > 
    <md-card-title-text > 
     <span class="md-headline">Demo Title {{i}}</span> 
     <span class="md-subhead">Demo Description</span> 
    </md-card-title-text>  
    </md-card-title> 
</md-card> 
</div> 

Controllare questo esempio: http://codepen.io/ktn/pen/jqNBOe

+0

a destra, ma cosa succede se le tue carte non sono tutte della stessa altezza – chrismarx

1

se ho capito la tua domanda giusta Quindi utilizzare questo codice e sostituire il ciao con tutto quello che vuoi

<md-grid-list md-cols-lg="12" md-cols-gt-lg="15" md-cols-xs="3" md-cols-sm="6" md-cols-md="9" md-row-height-gt-md="1:1" md-row-height-md="1:1" md-row-height="1:2" md-gutter-gt-md="16px" md-gutter-md="8px" md-gutter="4px"> 
      <md-grid-tile ng-repeat="contact in contacts" md-colspan="3" md-rowspan-gt-sm="4" style="background:red;"> 
       hello 
      </md-grid-tile> 
     </md-grid-list> 
+0

Questa è un'ottima risposta. L'unico problema è che la griglia ha alcune incompatibilità, come, per esempio, con lo scroll infinito – chrismarx

+0

@chrismarx sono d'accordo, ma la griglia non può essere tenuta all'interno di una ripetizione virtuale? lì possiamo implementare lo scroll infinito .. –

+0

Penso di averlo provato e ho avuto questo problema- https://github.com/angular/material/issues/5312 – chrismarx