Pergunta

Digamos que eu tenha a seguinte estrutura html:

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

É possível (e como) inserir um novo elemento <li>3</li> na ordem correta sem separar os elementos e reclassificá-los? A razão é, acredito que se você .detach () e .append () os elementos, você causará um refluxo de página (o que eu suponho que aconteceria de qualquer maneira se os elementos se movessem). Mas, por algum motivo, parece muito mais limpo inseri-lo no lugar certo do que anexar / desanexar / classificar / anexar.

Eu vi o seletor n-ésimo filho em jQuery e estou trabalhando com o framework underscore.js também (que fornece _.sortedIndex que me diz a posição correta do elemento), mas não consigo descobrir a maneira certa de colocá-lo lá.

Alguns antecedentes: Estou trabalhando com backbone.js e tenho uma coleção de itens. Então, presumo que preciso de uma Visualização da coleção (ou visualização por item da coleção?). Quando adiciono um elemento à coleção, tenho o comparador definido para que a coleção seja classificada corretamente, mas a Visualização na página não é classificada.

Para aqueles que chegam aqui pelo Google, aqui está o que acabei descobrindo no 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();

Execute aqui: http://jsfiddle.net/dlamotte/L4j3b/

Foi útil?

Solução

você pode usar um jQuery

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

página do violino: http://jsfiddle.net/Hrjks/

Melhor ainda:

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

mexer nisso: http://jsfiddle.net/Hrjks/1/

Outras dicas

Tive o mesmo problema recentemente e resolvi a seguinte função.

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()); 
} );​

Basicamente, ele obtém todos os filhos de parent e, em seguida, executa um filter.Se você só precisa comparar seus valores, pode fazer de forma simples, evitando o retorno de chamada, mas no meu caso foi necessário porque eu estava classificando por vários critérios.

Se você deseja classificar em ordem decrescente, basta substituir append por prepend, before por last e first por last e deve estar funcionando.

Sinta-se à vontade para brincar no meu playground: http://jsfiddle.net/crodas/FMEkb/5/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top