Pergunta

Não tenho ideia de por que esse código não está funcionando.
Lendo o documentação,
o templateHelpers deveria ser chamado.

Meu objetivo é passar this.collection.length para o modelo.

Alguma dica?obrigado.

Estou usando Backbone.Marionette v0.9.5


return Marionette.CompositeView.extend({
    className: 'user-board',

    template: usersTemplate,

    itemView: userItemView,

    initialize: function () {
        this.collection = new UseList();
        this.collection.fetch();
    },

    appendHtml: function (collectionView, itemView) {
        collectionView.$el.find('ul.users-list').append(itemView.el);
    },

    templateHelpers: function () {
        console.log(this.collection.length);
    },

    serializeData: function () {
        return {
            weekly: this.options.weekly,
            users_length: this.collection.length // here the length is zero
                                           // after the fetch the length is > 0
                                           // but in template remains 0
        };
    }
});

Para corrigir meu problema, tenho que fazer o seguinte ...

    initialize: function () {
        _.bindAll(this, 'render');
        this.collection = new NewCollection();
        this.collection.fetch({
            success: this.render
        });
    }

Existe uma maneira melhor de fazer isso funcionar?

Foi útil?

Solução

Lendo o Documentação de marionetes serializeData método, que é aquele que utiliza mixinTemplateHelpers, só é chamado Item View.render método aqui e no seu código atual você não renderiza nada

ATUALIZAR:Dessa forma toda vez que a coleção receber novos dados ela atualizará sua visualização com o novo comprimento

initialize: function () {
    _.bindAll(this, 'render');
    this.collection = new NewCollection();
    this.collection.fetch();
    this.collection.bind('reset', this.render);
}

Outras dicas

Este código declara apenas a visualização a.Você pode compartilhar o código que instancia a visualização e a exibe? templateHelpers será chamado e os dados passados ​​para o modelo quando o modelo é renderizado.Ou seja, você precisa mostrar a visualização em uma região que chama implicitamente o render método na visualização ou chame explicitamente o render método.

Ser útil, templateHelpers deve retornar um objeto.Por exemplo:

templateHelpers: function() {
    return {colLength: this.collection.length};
}

Uma coisa importante a ter em mente: fetch acionar uma solicitação AJAX feita de forma assíncrona.Se você quiser esperar pelo fetch para ter sucesso antes de renderizar a visualização, então você precisa usar Marionete.Async.


Atualização com base na pergunta de atualização

Para evitar ligar render da vista initialize e só faça isso quando render é chamado externamente, altere seu código para:

return Marionette.CompositeView.extend({
    className: 'user-board',

    template: usersTemplate,

    itemView: userItemView,

    initialize: function () {
        this.collection = new UseList();
        var that = this;
        this.defer = $.Deferred();
        this.collection.fetch({
            success: that.defer.resolve,
            error: that.defer.resolve
        });
    },

    appendHtml: function (collectionView, itemView) {
        collectionView.$el.find('ul.users-list').append(itemView.el);
    },

    templateHelpers: function () {
        console.log(this.collection.length);
        // For greater flexibility and maintainability, don't override `serializeData`.
        return {
            weekly: this.options.weekly,
            users_length: this.collection.length
        };
    },

    render: function() {
        var that = this,
            args = arguments;
        $.when(this.defer).done(function() {
            Marionette.CompositeView.prototype.apply(that, args);
        });
    }
}); 

estou resolvendo this.render tanto em caso de sucesso quanto de erro, caso contrário, se houver um erro, a visualização nunca será renderizada (a menos que você queira).

Observe que se você usar Marionette.Async então você retornaria this.defer na vista beforeRender e Marionette.Async cuidaria de atrasar a renderização.

Observe também que uma vez this.defer for resolvido, as renderizações futuras serão executadas quando chamadas, pois não há nada pelo que esperar, até this.defer foi redefinido programaticamente.

Pelo menos no Marionette v1.0.3, estou gostando do padrão em que a renderização é tratada automaticamente durante uma chamada para Region.show(), então eu chamo isso de um objeto controlador que possui a coleção e a passa para a visualização na instanciação. mostra a vista.Eu nem preciso colocar essa lógica em um retorno de chamada de sucesso de busca ou vincular explicitamente ao evento 'reset', porque a visualização composta/coleção do Marionette já sabe como (re) renderizar-se em caso de sucesso de busca (o que um depurador mostrará você).

Depois de usar uma configuração como a detalhada, você também pode usar ajudantes de modelo de forma um pouco mais útil do que foi descrito até agora.

Por exemplo,

Se você simplesmente inserir <%= functionName %> no modelo onde está tentando fazer com que o número apareça visualmente na página inicial (já que você deseja .length, eu vejo), a marionete simplesmente fará o trabalho para você.

Então assim:

--Template File--
<div id="followerCount"> <%= showCount %> </div>


--Helper Function in View--
templateHelpers: {
    showCount: function(){
                   return this.collection.length;
    } 
}

Espero que isso faça sentido ou pelo menos ajude alguém, talvez procurando uma maneira mais simples de integrar o banco de dados retornado JSON aos seus modelos.

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