2016-05-07 60 views
8

Ho riscontrato il seguente comportamento strano in ui-bootstrap e angolare 1.4. Quando metto direttiva footable tavolo all'interno di un pannello di bootstrap personalizzato, chiamato hpanel, il footable avviene inizialmente più posto rispetto al pannello stesso:Il contenuto della direttiva angolare non viene visualizzato, a meno che non si imposti manualmente il reflow della pagina

enter image description here

Ma se ridimensionare lo schermo (ad esempio facendo collassare il pannello Strumenti Sviluppatore qui), la direttiva footable stesso disegna e si inserisce all'interno del pannello:

enter image description here

problemi simili È importante sottolineare che ho vissuto con angular-c3 classifiche direttiv es (caricano in modo errato, superano le dimensioni di hpanel, ma a ridimensionamento della pagina si comportano bene), quindi probabilmente non è solo una direttiva rotta.

Hai visto qualcosa di simile?

DETTAGLI:

Di seguito è riportato un modello HTML che rappresenta la parte non funzionale della pagina. Lì abbiamo uno hpanel e al suo interno una tabella con angular-footable directive ^1.0.3, applicato ad esso.

Ecco il modello (toolList.html):

<div class="content"> 
    <div class="row"> 
     <div class="col-lg-12"> 
      <div class="hpanel"> 
       <div class="panel-heading"> 
        <div class="panel-tools"> 
         <a class="showhide"><i class="fa fa-chevron-up"></i></a> 
         <a class="closebox"><i class="fa fa-times"></i></a> 
        </div> 
        Available tools. 
       </div> 
       <div class="panel-body"> 
        <input type="text" class="form-control input-sm m-b-md" id="filter" placeholder="Search in table"> 
        <table id="example1" class="footable table table-stripped toggle-arrow-tiny" data-page-size="8" data-filter=#filter> 
         <thead> 
         <tr> 
          <th data-toggle="true">Id</th> 
          <th>Class</th> 
          <th>Label</th> 
          <th>Description</th> 
          <th data-hide="all">Owner</th> 
          <th data-hide="all">Contributor</th> 
          <th data-hide="all">Inputs</th> 
          <th data-hide="all">Outputs</th> 
          <th data-hide="all">Base command</th> 
          <th data-hide="all">Arguments</th> 
          <th data-hide="all">Requirements</th> 
          <th data-hide="all">Hints</th> 
         </tr> 
         </thead> 
         <tbody> 
         <tr ng-repeat="tool in vm.tools"> 
          <td><a ui-sref="tool-detail({id: tool.id})">{{tool.id}}</a></td> 
          <td>{{tool.tool_class}}</td> 
          <td>{{tool.label}}</td> 
          <td>{{tool.description}}</td> 
          <td>{{tool.owner}}</td> 
          <td>{{tool.contributor}}</td> 
          <td>{{tool.baseCommand}}</td> 
          <td>{{tool.arguments}}</td> 
          <td>{{tool.requirements}}</td> 
          <td>{{tool.hints}}</td> 
         </tr> 
         </tbody> 
         <tfoot> 
         <tr> 
          <td colspan="5"> 
           <ul class="pagination pull-right"></ul> 
          </td> 
         </tr> 
         </tfoot> 
        </table> 

       </div> 
      </div> 
     </div> 
    </div> 
</div> 

La direttiva footable ha lo scopo di nascondere alcune colonne della tabella e mostrare loro su click su una riga della tabella. Fornisce anche l'impaginazione. Non sembra funzionare sul caricamento della pagina, ma quando ridimensiono la pagina e le dimensioni dello schermo incrociano il margine del tipo di supporto (in modo che dallo schermo di dimensioni medie diventi grande schermo in termini di avvio css), i pulsanti di paginazione appaiono e le colonne che devono essere nascoste sono nascoste.

Ecco come importare la direttiva footable nel mio modulo principale app.js:

require("footable/js/footable"); 
require("footable/js/footable.filter"); 
require("footable/js/footable.striping"); 
require("footable/js/footable.sort"); 
require("footable/js/footable.paginate"); 
require("footable/css/footable.core.css") 
require("angular-footable"); 

angular.module("app", [ 
    ..., 
    "ui.footable", 
]) 

Io uso webpack per caricare tutti i moduli e bower per installare le dipendenze.

hpanel è solo una classe scss, qui è la sua definizione:

/* Panels */ 
.hpanel > .panel-heading { 
    color: inherit; 
    font-weight: 600; 
    padding: 10px 4px; 
    transition: all .3s; 
    border: 1px solid transparent; 
} 

.hpanel .hbuilt.panel-heading { 
    border-bottom: none; 
} 

.hpanel > .panel-footer, .hpanel > .panel-section { 
    color: inherit; 
    border: 1px solid $border-color; 
    border-top: none; 
    font-size: 90%; 
    background: $color-bright; 
    padding: 10px 15px; 
} 

.hpanel.panel-collapse > .panel-heading, .hpanel .hbuilt { 
    background: #fff; 
    border-color: $border-color; 
    border: 1px solid $border-color; 
    padding: 10px 10px; 
    border-radius: 2px; 
} 

.hpanel .panel-body { 
    background: #fff; 
    border: 1px solid $border-color; 
    border-radius: 2px; 
    padding: 20px; 
    position: relative; 
} 


.hpanel.panel-group .panel-body:first-child { 
    border-top: 1px solid $border-color; 
} 

.hpanel.panel-group .panel-body { 
    border-top: none; 
} 

.panel-collapse .panel-body { 
    border: none; 
} 

.hpanel { 
    background-color: none; 
    border: none; 
    box-shadow: none; 
    margin-bottom: 25px; 
} 

.panel-tools { 
    display: inline-block; 
    float: right; 
    margin-top: 0; 
    padding: 0; 
    position: relative; 
} 

.hpanel .alert { 
    margin-bottom: 0; 
    border-radius: 0; 
    border: 1px solid $border-color; 
    border-bottom: none; 
} 

.panel-tools a { 
    margin-left: 5px; 
    color: lighten($color-text, 20%); 
    cursor: pointer; 
} 

.hpanel.hgreen .panel-body { 
    border-top: 2px solid $color-green; 
} 

.hpanel.hblue .panel-body { 
    border-top: 2px solid $color-blue; 
} 

.hpanel.hyellow .panel-body { 
    border-top: 2px solid $color-yellow; 
} 

.hpanel.hviolet .panel-body { 
    border-top: 2px solid $color-violet; 
} 

.hpanel.horange .panel-body { 
    border-top: 2px solid $color-orange; 
} 

.hpanel.hred .panel-body { 
    border-top: 2px solid $color-red; 
} 

.hpanel.hreddeep .panel-body { 
    border-top: 2px solid $color-red-deep; 
} 

.hpanel.hnavyblue .panel-body { 
    border-top: 2px solid $color-navy-blue; 
} 

.hpanel.hbggreen .panel-body { 
    background: $color-green; 
    color: #fff; 
    border:none; 
} 

.hpanel.hbgblue .panel-body { 
    background: $color-blue; 
    color: #fff; 
    border:none; 
} 

.hpanel.hbgyellow .panel-body { 
    background: $color-yellow; 
    color: #fff; 
    border:none; 
} 

.hpanel.hbgviolet .panel-body { 
    background: $color-violet; 
    color: #fff; 
    border:none; 
} 

.hpanel.hbgorange .panel-body { 
    background: $color-orange; 
    color: #fff; 
    border:none; 
} 

.hpanel.hbgred .panel-body { 
    background: $color-red; 
    color: #fff; 
    border:none; 
} 

.hpanel.hbgreddeep .panel-body { 
    background: $color-red-deep; 
    color: #fff; 
    border:none; 
} 

.hpanel.hbgnavyblue .panel-body { 
    background: $color-navy-blue; 
    color: #fff; 
    border:none; 
} 

.panel-group .panel-heading { 
    background-color: $color-bright; 
} 

.small-header .hpanel { 
    margin-bottom: 0; 
} 

.small-header { 
    padding: 0 !important; 
} 

.small-header .panel-body { 
    padding: 15px 25px; 
    border-right: none; 
    border-left: none; 
    border-top: none; 
    border-radius: 0; 
    // background: $color-bright; 
} 

.panel-body h5, .panel-body h4 { 
    font-weight: 600; 
} 

.small-header .panel-body h2 { 
    font-size: 14px; 
    font-weight: 600; 
    text-transform: uppercase; 
    margin: 0 0 0 0; 
} 

.small-header .panel-body small { 
    color: lighten($color-text, 10%); 
} 

.hbreadcrumb { 
    padding: 2px 0px; 
    margin-top: 6px; 
    margin-bottom: 0px; 
    list-style: none; 
    background-color: #fff; 
    font-size: 11px; 

    > li { 
    display: inline-block; 

    + li:before { 
     padding: 0 5px; 
     color: $color-navy-blue; 
    } 
    } 

    > .active { 
    color: lighten($color-text,20%); 
    } 
} 

.wrapper { 
    padding: 10px 20px; 
} 

.hpanel.collapsed .panel-body, .hpanel.collapsed .panel-footer { 
    display: none; 
} 

.hpanel.collapsed .fa.fa-chevron-up:before { 
    content: "\f078"; 
} 
.hpanel.collapsed .fa.fa-chevron-down:before { 
    content: "\f077"; 
} 

.hpanel.collapsed.panel-collapse .panel-body { 
    border-width: 0 1px 1px 1px; 
    border-color: $border-color; 
    border-style: solid; 
} 

.hpanel.collapsed .hbuilt.panel-heading { 
    border-bottom: 1px solid $border-color; 
} 

body.fullscreen-panel-mode { 
    overflow-y: hidden; 
} 

.hpanel.fullscreen { 
    z-index: 2030; 
    position: fixed; 
    top: 0; 
    left: 0; 
    right: 0; 
    bottom: 0; 
    overflow: auto; 
    margin-bottom: 0; 
} 

.hpanel.fullscreen .showhide { 
    display: none; 
} 

.hpanel.fullscreen .panel-body { 
    min-height: calc(100% - 77px); 
} 

Ecco tool.module.js di file, che anima il modello:

import angular from "angular"; 

var ToolResource = require("workflow/tool/tool.service"); 

class ToolListController { 
    // @ngInject 
    constructor($location, $stateParams, $state, tools) { 
     this.$location = $location; 
     this.$state = $state; 
     this.$stateParams = $stateParams; 

     this.tools = tools; 
    } 
} 

// @ngInject 
function routesList($stateProvider) { 
    $stateProvider.state("tool-list", { 
     url: "/tool", 
     parent: "layout", 
     templateUrl: "/app/workflow/tool/toolList.html", 
     controller: "ToolListController", 
     controllerAs: "vm", 
     data: { 
      pageTitle: "Tool", 
      pareDesc: "List of tools, available for workflow construction.", 
     }, 
     resolve: { 
      ToolResource: "ToolResource", 
      tools: function(ToolResource) { 
       return ToolResource.query().$promise; 
      } 
     } 
    }); 
} 

module.exports = angular.module("tool", []) 
    .service('ToolResource', ToolResource) 
    .controller('ToolListController', ToolListController) 
    .config(routesList); 

tool.service.js:

module.exports = function ToolResource($resource) { 
    return $resource('/api/tool/:id', {id: '@id'}); 
} 

RISPOSTA : La comunità è fantastica!

  • 1.5 anni fa questa direttiva è stato creato
  • 12 giorni fa Questo bug è stato risolto by Alexryan in his fork
  • 10 giorni fa ho postato questa domanda su StackOverflow
  • otto giorni fa, ho messo una taglia su questo argomento
  • 7 giorni fa ziscloud ha approvato oggi richiesta di pull
  • al mattino la bontà è scaduto e nel momento giusto Walfrat scoperto che il bug è stato risolto

Quindi, sì, è stato un bug nella direttiva che ha reso la sua disegnare elfo prima di ottenere i dati dal server. Con il bugfix ho appena aggiunto l'attributo load-when="vm.tools" alla direttiva e ora funziona bene.

Grazie, Alexryan, ziscloud, Walfrat e altri commentatori/risponditori. StackOverflow e Github hanno appena reso la mia giornata!

+0

Le schermate non forniscono informazioni sufficienti per aiutarti, per favore mostraci del codice. –

+0

@RobJ Hai ragione. Ho aggiunto il codice e le spiegazioni pertinenti. Per favore, fammi sapere, se trovi che alcuni dettagli sono sbagliati. –

+0

stai caricando i dati dello strumento in modo asincrono, quindi inizialmente la direttiva footable che stai utilizzando non sa quale sia la larghezza della finestra, puoi usare $ (window) .resize() dopo aver ottenuto i dati, potrebbe essere in un setinterval, questo la soluzione che sto fornendo potrebbe essere un hack e questo deve essere risolto nella direttiva footable, –

risposta

1

Si sta utilizzando questa direttiva? https://github.com/ziscloud/angular-footable/blob/master/src/angular-footable.js. È una direttiva fatta in casa (ovvero non elaborata dall'editor del footable), quindi non può essere implementata correttamente per funzionare con Angularjs.

Guardando il codice sembra che sia necessario utilizzare un attributo load-when se si desidera ritardare l'inizializzazione della griglia anche se si utilizza l'attributo di risoluzione nel proprio stato, può valere la pena testarlo. load-when deve essere una matrice vuota all'avvio e attiverà il carico dopo che l'array non sarà più vuoto, ma i dati associati non verranno utilizzati per l'inizializzazione da quello che ho visto.

Nota: non ero in grado di impostare una corretta plnkr me stesso, non so la versione che si sta utilizzando (e con quale versione jQuery) e collegamenti online non sembra disponibile.

+0

Grazie per il suggerimento. La versione della direttiva è 1.0.3, angular 1.4, jquery 2.Puoi fornire un manuale di base per l'utilizzo di "load-when", aggiungerò io stesso i dettagli? –

+0

Penso che si possa semplicemente collegare 'load-when' a' tools' per testare. Non conosco né footable né questa direttrice, ho appena controllato il codice – Walfrat

+0

Scusate, non conosco affatto il pattern 'load-when' in angolare e non posso google-out di cosa si tratta. Puoi dare qualche esempio di 'load-when'? –

1

Poiché i dati vengono caricati in modo asincrono (come menzionato nei commenti), il tuo html viene sottoposto a rendering prima che abbia dati in esso contenuti. Ciò significa che la direttiva potrebbe essere licenziata troppo presto (se sta tentando di adattarsi in base ai dati). In genere, in questo scenario, dovrai lanciare un ng-if sulla parte del tuo html che dipende dal caricamento dei dati (e mostrare una gif di caricamento o qualcosa al suo posto). È possibile eseguire ng-if off dei dati stessi definiti, oppure mantenere un booleano separato che si imposta una volta risolta la promessa.

+0

Aspetta, restituisco una promessa da 'resolve', quindi, secondo la documentazione di ui-router (https://github.com/angular-ui/ui-router/wiki#resolve) il controller non verrà istanziato prima che i dati siano inverosimile. Il rendering dello stato può iniziare senza un controller istanziato? –