ExtJS Grid Plugin

2034
Mchl

The code below is a plugin I wrote for Ext.grid.GridPanel, which basically allows you to have a bit more control over how rows are striped in the grid. By default you can only have every other row in alternate colour. With this plugin you an have for example 5 in basic color, 5 in alternate and so on.

What bothers me about it, is that it basically is 100+ lines copied from Ext.grid.GridView with no more than 10 lines of my modifications. I would love to know if there's a way to do it in a more elegant way.

My second concern is with that it's a plugin for Ext.grid.GridPanel, but it actually modifies the underlying Ext.grid.GridView. As far as I know, there is no way to attach a plugin to a GridView with current framework architecture, but perhaps you DO know the way.

Legal stuff: The code is largely based on ExtJS source code, and as such it's released under GNU GPL license v3 license

MyNamespace.grid.plugins.RowStriper = Ext.extend(Object, {
  constructor : function(config) {
    config = config || {};
    Ext.apply(this, config);
  },
  init : function(parent) {
        if (parent instanceof Ext.grid.GridPanel) {
            this.parent = parent;
            this.parent.stripeInterval = this.stripeInterval;
            parent.on('destroy', this.onDestroy, this);
            Ext.apply(parent.getView(), this.parentViewOverrides);
        }
  },
  onDestroy : Ext.emptyFn,
    parentViewOverrides : {
        doRender : function(columns, records, store, startRow, colCount, stripe) {
      var templates    = this.templates,
          cellTemplate = templates.cell,
          rowTemplate  = templates.row,
          last         = colCount - 1;

      var tstyle = 'width:' + this.getTotalWidth() + ';';

      // buffers
      var rowBuffer = [],
          colBuffer = [],
          rowParams = {tstyle: tstyle},
          meta      = {},
          column,
          record;

      //build up each row's HTML
      for (var j = 0, len = records.length; j < len; j++) {
        record    = records[j];
        colBuffer = [];

        var rowIndex = j + startRow;

        //build up each column's HTML
        for (var i = 0; i < colCount; i++) {
          column = columns[i];

          meta.id    = column.id;
          meta.css   = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
          meta.attr  = meta.cellAttr = '';
          meta.style = column.style;
          meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);

                    if (Ext.isEmpty(meta.value)) {
            meta.value = '&#160;';
          }

          if (this.markDirty && record.dirty && Ext.isDefined(record.modified[column.name])) {
            meta.css += ' x-grid3-dirty-cell';
          }

          colBuffer[colBuffer.length] = cellTemplate.apply(meta);
        }

        //set up row striping and row dirtiness CSS classes
        var alt = [];

                if (stripe && (rowIndex % (this.grid.stripeInterval * 2)) > (this.grid.stripeInterval - 1)) {
          alt[0] = 'x-grid3-row-alt';
        }

        if (record.dirty) {
          alt[1] = ' x-grid3-dirty-row';
        }

        rowParams.cols = colCount;

        if (this.getRowClass) {
          alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
        }

        rowParams.alt   = alt.join(' ');
        rowParams.cells = colBuffer.join('');

        rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
      }

      return rowBuffer.join('');
    },
        processRows : function(startRow, skipStripe) {
        if (!this.ds || this.ds.getCount() < 1) {
              return;
      }

      var rows = this.getRows(),
                    len  = rows.length,
                    i, r;

      skipStripe = skipStripe || !this.grid.stripeRows;
            var stripeInterval = this.grid.stripeInterval || 1;
      startRow   = startRow   || 0;

      for (i = 0; i<len; i++) {
                r = rows[i];
                if (r) {
                    r.rowIndex = i;
          if (!skipStripe) {
                        r.className = r.className.replace(this.rowClsRe, ' ');
            if ((i % (stripeInterval * 2)) > (stripeInterval - 1)){
                            r.className += ' x-grid3-row-alt';
            }
          }
        }
      }

      // add first/last-row classes
      if (startRow === 0) {
                Ext.fly(rows[0]).addClass(this.firstRowCls);
      }

      Ext.fly(rows[rows.length - 1]).addClass(this.lastRowCls);
        }
  }
});
Antworten
12
Relevante Links: docs http://dev.sencha.com/deploy/dev/docs/?class=Ext.grid.GridPanel und Quelle: http://dev.sencha.com/deploy/dev/docs/source/GridPanel .html # cls-Ext.grid.GridPanel (stimmt das?). TryPyPy vor 9 Jahren 0
Jep. Obwohl der größte Teil des Codes aus der http://dev.sencha.com/deploy/dev/docs/?class=Ext.grid.GridView-Komponente stammt (Quelle http://dev.sencha.com/deploy/dev/docs/ source / GridView.html # cls-Ext.grid.GridView) Mchl vor 9 Jahren 1

1 Antwort auf die Frage

4
TryPyPy

Ich sehe nicht viel, wie man die Duplizierung verbessern kann: Sie erweitern Code, der leider nicht erweitert werden sollte.

Sie können jedem dabei helfen, Ihren Code in der Wildnis zu finden, indem Sie Änderungen hervorheben und möglicherweise erklären, warum Sie die Berechnungen durchführen, die Sie durchführen. Wie würden Sie Ihren Code generalisieren, um zwischen drei oder mehr Zeilenstilen zu wechseln?

    //set up row striping and row dirtiness CSS classes
    var alt = [];

/// -> Comment about how you're making the stripe interval magic happen here
            if (stripe && (rowIndex % (this.grid.stripeInterval * 2)) > (this.grid.stripeInterval - 1)) {
/// -^ Consider breaking this up into assignment into a var and subsequent if, or 
///    even nesting ifs: it might be more readable by separating logical steps.
///    A helper to be used below would be an option, and if you're going to generalize
///    it could make extending easier.

      alt[0] = 'x-grid3-row-alt';
    }

/// [...]

     if (!skipStripe) {
                    r.className = r.className.replace(this.rowClsRe, ' ');
        if ((i % (stripeInterval * 2)) > (stripeInterval - 1)){
                        r.className += ' x-grid3-row-alt';
/// -^ Same comments apply here, specially about highlighting your changes.

Sie könnten die Modularität in Ihrer Version verbessern und dann einen Patch vorschlagen, um die Arbeit mit Upstream zu vereinfachen, sodass wir nicht das gleiche Schicksal erleiden müssen wie Sie;)

Danke für die Eingabe! Ich habe nicht wirklich überlegt, mehr als zwei verschiedene Stile zu haben. Dies ist ein Plugin, das ich für eine Intranet-App in meinem Unternehmen erstellt habe. Es war also nie beabsichtigt, in der Wildnis veröffentlicht zu werden. Deshalb fehlen ihm Kommentare, und auch die Einrückung scheint abgeschaltet zu sein (habe es nur bemerkt). Was das Einreichen eines Patches an ExtJS-Entwickler betrifft, werde ich warten, bis es eine Betaversion 4.0 gibt, um zu sehen, wie sich (falls) die Situation dort ändert. Es soll mehr Haken für Plugins geben. Mchl vor 9 Jahren 1