2016-04-02 8 views
0

Ich arbeite an einer Anwendung mit Laravel 5.2 + Vuejs + Vueify und ich habe eine Reihe von Objekt in einer Tabelle aufgeführt, aber ich habe 2 Probleme.Vue.js orderBy funktioniert nicht richtig mit Groß- und Kleinbuchstaben

1. orderBy arbeitet mit Groß- und Klein getrennt

Die orderBy mit Rekord getrennt bewirbt, wo die ersten Buchstaben in Groß- und Kleinschreibung ist!

2. Angebote Gebe die auf dem Filterfeld

Typing „Á gua“ auf dem Filterfeld wegen der akuten Akzent auf dem Buchstaben A das „Agua“ Ergebnis nicht finden, und ich möchte den Akzent zu ignorieren ... ist das möglich?

JS Datei

Vue.filter('pmlOrderBy', function(arr, sortKey, reverse) { 

    if (!sortKey) { 
    return arr; 
    } 
    var order = (reverse && reverse < 0) ? -1 : 1; 

    // sort on a copy to avoid mutating original array 
    return arr.slice().sort(function(a, b) { 
    if (sortKey !== '$key') { 
     if (Vue.util.isObject(a) && '$value' in a) a = a.$value; 
     if (Vue.util.isObject(b) && '$value' in b) b = b.$value; 
    } 
    a = Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, sortKey) : a; 
    b = Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, sortKey) : b; 

    a = a.toLowerCase(); 
    b = b.toLowerCase(); 

    //   return a.localeCompare(b) * order; 

    return a === b ? 0 : a > b ? order : -order; 
    }); 
}); 


new Vue({ 

    el: 'body', 

    data: { 
    record: {}, 
    selected: [], 
    list: [{ 
     name: 'Google', 
     id: 1, 
    }, { 
     name: 'Água', 
     id: 2, 
    }, { 
     name: 'Agua Branca', 
     id: 3, 
    }, { 
     name: 'first time', 
     id: 4, 
    }, { 
     name: 'boston', 
     id: 5, 
    }, { 
     name: 'Type', 
     id: 6, 
    }, { 
     name: 'Facebook', 
     id: 7, 
    }, ], 
    sortProperty: 'name', 
    sortDirection: 1, 
    }, 

    methods: { 

    sort: function(property) { 
     this.sortProperty = property; 
     this.sortDirection = (this.sortDirection == 1) ? -1 : 1; 
    }, 

    } 

}); 

HTML Datei

<div class="container"> 
    <input type="text" v-model="textFilter" class="form-control" placeholder="Type to filter..."> 
</div> 

<hr> 

<div class="container"> 
    <div class="alert alert-info">Click at the TH to sort</div> 
    <table class="table table-striped table-bordered"> 
    <thead> 
     <tr> 
     <th @click="sort('id')" style="cursor: pointer;">Id</th> 
     <th @click="sort('name')" style="cursor: pointer;">Name</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr v-for="r in list | filterBy textFilter | pmlOrderBy sortProperty sortDirection"> 
     <td class="text-center" style="width:90px">{{ r.id }}</td> 
     <td>{{ r.name }}</td> 
     </tr> 
    </tbody> 
    </table> 
</div> 

JS Bin

==== ==== EDITED

Als Taylor und RainningChain mir geholfen haben zu brüllen sind wir fast da!

fand ich this article und den Code und die JS Bin oben aktualisiert, aber das Problem ist jetzt:

  • Es sort richtig ist, aber wenn ich versuche, TH bremst auf eine andere andere Spalte klicken zu sortieren.
  • Das Problem mit spezieller Gäbe es noch =/

jedermann?

Danke!

Antwort

1

Um dies zu erreichen, müssten Sie Ihren eigenen Filter erstellen.

Erweitern Vue orderBy Filter, dies wäre eine funktionale Lösung für beide Ihre Probleme.

// This was originally copied from the Vue source 
// File: src/filters/array-filters.js 
function orderByWords (arr, sortKey, reverse) { 
    arr = convertArray(arr) 
    if (!sortKey) { 
    return arr 
    } 
    var order = (reverse && reverse < 0) ? -1 : 1 
    // sort on a copy to avoid mutating original array 
    return arr.slice().sort(function (a, b) { 
    if (sortKey !== '$key') { 
     if (isObject(a) && '$value' in a) a = a.$value 
     if (isObject(b) && '$value' in b) b = b.$value 
    } 
    a = isObject(a) ? getPath(a, sortKey) : a 
    b = isObject(b) ? getPath(b, sortKey) : b 
    return a.localeCompare(b) * order 
    }) 
} 

Das Fleisch des Filters ist dieser Ausschnitt hier: a.localeCompare(b)

Die String.prototype.localeCompare Methode vergleicht zwei Strings und gibt einen Wert integer basierend darauf, ob die Anfangsfolge (a) kommt, vor oder nach dem Vergleich String (b).

UPDATE

Es stellt sich heraus das Filter zu brechen, weil Number.prototype.localeCompare existiert nicht ... wer hätte das gedacht?

Also können wir ein wenig Trickbetrügerei verwenden, um dies an allem zu arbeiten.

Vue.filter('pmlOrderBy', function (arr, sortKey, reverse) { 
    if (!sortKey) { 
     return arr; 
    } 
    var order = (reverse && reverse < 0) ? -1 : 1; 

    // sort on a copy to avoid mutating original array 
    return arr.slice().sort(function (a, b) { 
     if (sortKey !== '$key') { 
      if (Vue.util.isObject(a) && '$value' in a) a = a.$value; 
      if (Vue.util.isObject(b) && '$value' in b) b = b.$value; 
     } 
     a = Vue.util.isObject(a) ? Vue.parsers.path.getPath(a, sortKey) : a; 
     b = Vue.util.isObject(b) ? Vue.parsers.path.getPath(b, sortKey) : b; 

     return (''+a).localeCompare((''+b)) * order; 
    }); 
}); 

Die Schlüsselzeile ist die letzte Zeile des Filters. (''+a).localeCompare wird a in eine String erzwingen und dann die localeCompare Methode aufrufen.

+0

Erwähnenswerte benutzerdefinierte Filter können über 'Vue.filter (name, customOrderByFunc)' erstellt werden. – RainingChain

+0

Jungs, ich habe immer noch ein Problem! Ich habe die Frage aktualisiert! Hast du irgendeine Idee? @rainningchain –

+0

@GustavoBissolli Ich habe meine Antwort aktualisiert, um einen aktualisierten Filter für Sie zu enthalten. –

Verwandte Themen