Question

Disons que j'ai le code html suivant la structure:

<ul>
  <li>1</li>
  <li>2</li>
  <li>4</li>
</ul>

Est-il possible (et comment) pour insérer un nouvel élément <li>3</li> dans l'ordre correct sans détacher les éléments et les recours?Raison d'être, je crois que si vous .detach() et .append() les éléments, vous provoquerez une page de brasage (qui, je suppose, se produirait de toute façon, si les éléments se déplacer).Mais pour une raison quelconque, il semble beaucoup plus propre pour l'insérer dans le bon endroit vs ajouter/détacher/tri/append.

J'ai vu le nth-child sélecteur jQuery et je travaille avec le underscore.js cadre trop (qui fournit _.sortedIndex qui me dit que la bonne position de l'élément), mais je n'arrive pas à trouver la bonne façon de le mettre là.

Un peu de contexte:Je suis en train de travailler avec backbone.js et j'ai une collection d'éléments.Alors je suppose que j'ai besoin d'une Vue de la collecte (ou vue par élément dans la collection?).Quand j'ajoute un élément à la collection, j'ai le comparateur de sorte que la collection est trié correctement, mais la Vue sur la page n'est pas triée.

Pour ceux arriver ici via google, voici ce que j'ai finalement venu avec dans backbone.js:

Item = Backbone.Model.extend({});

ItemList = Backbone.Collection.extend({
    model: Item,

    comparator: function(item) {
        return item.get('id');
    }
});

ItemView = Backbone.View.extend({
    tagName: 'li',
    className: 'item',

    initialize: function() {
        _.bindAll(this, 'render');
        this.model.bind('change', this.render);
        this.model.view = this;
    },

    render: function() {
        $(this.el).text(this.model.get('name'));
        return this;
    }
});

App = Backbone.View.extend({
    el: $('#mylist'),

    initialize: function() {
        _.bindAll(this, 'add_one', 'add_all', 'render');

        this.items = new ItemList();
        this.items.bind('add', this.add_one);
        this.items.bind('refresh', this.add_all);
        this.items.bind('all', this.render);

        this.items.add(new Item({id: 2, name: 'two'}));
        this.items.add(new Item({id: 5, name: 'five'}));
        this.items.add(new Item({id: 1, name: 'one'}));
        this.items.add(new Item({id: 4, name: 'four'}));
        this.items.add(new Item({id: 3, name: 'three'}));        
        this.items.add(new Item({id: 6, name: 'six'}));
        this.items.add(new Item({id: 5.5, name: 'five.five'}));
    },

    add_one: function(item) {
        var view = new ItemView({model: item});
        var visible = this.$(view.tagName+'.'+view.className);
        var newel = view.render().el;
        var idx = this.items.indexOf(item);
        if (visible.length == idx) {
            $(this.el).append(newel);
        }
        else {
            visible.eq(idx).before(newel);
        }
    },

    add_all: function() {
        this.items.each(this.add_one);
    }
});

app = new App();

Exécuter ici: http://jsfiddle.net/dlamotte/L4j3b/

Était-ce utile?

La solution

vous pouvez utiliser une jQuery

$('li').eq(1).after('<li>3</li>');

Page de violon: http://jsfiddle.net/hrjks/

Mieux encore:

var myindex = 3;
var insertPoint = myindex -2;
$('li').eq(insertPoint).after('<li>' + myindex +'</li>');

Vidule pour ceci:http://jsfiddle.net/hrjks/1/

Autres conseils

J'ai eu le même problème récemment et je fixe avec la fonction suivante.

function sortInsert(parent, element, fnc) {
    var stack = parent.children().filter(function() {
        return fnc($(this), element) > 0;
    });       
    if (stack.length == 0) {
        parent.append(element);
    } else {
        stack.first().before(element);
    }
}

sortInsert($('ul'), $('<li>1</li>'), function(e, a) { 
    return parseInt(e.html()) - parseInt(a.html()); 
} );​

C'est en gros tous les enfants de parent, puis de faire un filter.Si vous avez seulement besoin de comparer ses valeurs, vous pouvez le faire en évitant le rappel, mais dans mon cas, il était nécessaire que j'étais le tri par plusieurs critères.

Si vous souhaitez trier en ordre décroissant il suffit de remplacer append par prepend, before par last et first pour last et cela devrait fonctionner.

N'hésitez pas à jouer dans mon terrain de jeu: http://jsfiddle.net/crodas/FMEkb/5/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top