27 votes

Backbone.js - étant Donné un élément, comment puis-je obtenir la vue?

J'ai créé un tas de Backbone.js les vues. Chaque vue est associée à un élément (view.el).

Étant donné un élément sur la page de contexte de la vue - ce qui serait le meilleur moyen d'obtenir le point de vue de l'élément?

Par exemple, dire que certains événement affecte un tas d'éléments sur une page et je veux appeler une méthode sur chaque vue associée à des éléments affectés.

Un autre moyen serait d'affecter l'affichage de l'élément de données, mais je me demande si j'ai raté quelque chose de plus intelligent:

var myview = BackBone.View.extend({
    initialize: function(options) {
        $(this.el).data('view', this);
        ...
    }
});

(Je suis en utilisant colonne vertébrale avec jQuery 1.5.)

12voto

Ed . Points 2160

Je viens d'écrire un plugin jQuery pour cela. Il utilise également l' .data() méthode.

Inscription:

J'ai enveloppé / mandaté l'épine Dorsale de Vue setElement méthode pour joindre les données nécessaires à l'affichage de $el de la propriété.

L'inscription se fait en coulisses comme suit:

$(myViewsEl).backboneView(myView);

Récupération:

Le plugin traverse la hiérarchie DOM (à l'aide d' .closest()) jusqu'à ce qu'il trouve un élément avec la saisie de données requises, j'.e un élément du DOM avec une vue associée:

var nearestView = $(e.target).backboneView();

En outre, nous pouvons spécifier de quel type de colonne vertébrale Vue que l'on veut obtenir, en continuant la hiérarchie jusqu'à ce que nous trouver un exemple de même type:

var nearestButtonView = $(e.target).backboneView(ButtonView);

JSFiddle Exemple:

Peut être trouvé ici.

Notes:

J'espère que je me trompe en pensant que il n'y a pas de fuites de mémoire en cause ici; Un 'dissocier' est exécuté si setElement est appelé une seconde fois, et depuis la suppression d'une vue de l'élément appels .remove() par défaut, ce qui détruit toutes les données ainsi. Laissez-moi savoir si vous pensez différemment.

Le code du plugin:

(function($) {

    // Proxy the original Backbone.View setElement method:
    // See: http://backbonejs.org/#View-setElement

    var backboneSetElementOriginal = Backbone.View.prototype.setElement;

    Backbone.View.prototype.setElement = function(element) {
        if (this.el != element) {
            $(this.el).backboneView('unlink');                    
        }

        $(element).backboneView(this);    

        return backboneSetElementOriginal.apply(this, arguments);
    };

    // Create a custom selector to search for the presence of a 'backboneView' data entry:
    // This avoids a dependency on a data selector plugin...

    $.expr[':'].backboneView = function(element, intStackIndex, arrProperties, arrNodeStack) {
        return $(element).data('backboneView') !== undefined;        
    };

    // Plugin internal functions:

    var registerViewToElement = function($el, view) {
        $el.data('backboneView', view);
    };

    var getClosestViewFromElement = function($el, viewType) {
        var ret = null;

        viewType = viewType || Backbone.View;

        while ($el.length) {
            $el = $el.closest(':backboneView');
            ret = $el.length ? $el.data('backboneView') : null;

            if (ret instanceof viewType) {
                break;
            }
            else {
                $el = $el.parent();
            }           
        }

        return ret;                
    };

    // Extra methods:

    var methods = {

        unlink: function($el) {
            $el.removeData('backboneView');        
        }

    };

    // Plugin:

    $.fn.backboneView = function() {
        var ret = this;
        var args = Array.prototype.slice.call(arguments, 0);

        if ($.isFunction(methods[args[0]])) {
            methods[args[0]](this);                        
        }
        else if (args[0] && args[0] instanceof Backbone.View) {
            registerViewToElement(this.first(), args[0]);                
        }
        else {
            ret = getClosestViewFromElement(this.first(), args[0]);
        }

        return ret;        
    }        

})(jQuery);

6voto

Bill Eisenhauer Points 4700

Chaque vue peut s'inscrire pour les événements DOM. En tant que tel, chaque vue avec le type d'élément que vous êtes intéressé doit s'inscrire dans les DOM événement et ensuite attribuer à un événement répondant fonction qui fait ce que vous voulez. Si vous avez besoin de SÉCHER les choses, de les utiliser mixin techniques de mélange dans la fonction.

Je pense que peut-être que cette solution est plus facile que vous pouvez avoir initialement imaginé. Juste laisser les points de vue, faire le travail qu'ils sont censés faire.

1voto

Mario Points 2286

Vous pourriez maintenir une vue de hachage (dictionnaire) qui utilise l'élément en tant que clé et retourne le voir (ou vues).

http://www.timdown.co.uk/jshashtable/

0voto

Vladimir Gurovich Points 5408

Étant donné que chaque point de vue a une référence au modèle de son affichage, ce que je voudrais faire est d'attribuer l'id du modèle à la vue de l'élément associé(heureusement nous, qui n'est pas affecté par les changements de l'extérieur de l'événement). Assurez-vous également que le modèle a une référence à son point de vue. Alors ces modèles stockés dans une base de collecte.

Avec cette configuration, une fois qu'il arrive quelque chose à un élément, vous utilisez les éléments id pour récupérer modèle correspondant du Backbone de collecte que vous avez créé précédemment, puis ce modèle va vous donner votre point de vue de référence.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X