Backbone.js的 - 给定一个元素,我怎么认为? [英] Backbone.js - Given an element, how do I get the view?

查看:74
本文介绍了Backbone.js的 - 给定一个元素,我怎么认为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一堆 Backbone.js的意见。每个视图都有一个相关的元素( view.el )。

I've created a bunch of Backbone.js views. Each view has an associated element (view.el).

由于页面上的元素 - 从视图的背景 - 这将是获得该元素的视图的最佳方式。

Given an element on the page — out of context of the view — what would be the best way to get the view for the element?

举例来说,假设某个事件影响了一堆网页上的元素的,我想呼吁与受影响的元素相关联的每个视图的方法。

For example, say some event affects a bunch of elements on a page and I want to call a method on every view associated with the affected elements.

一个方法是指定的视图元素的数据,但我想知道如果我错过了一些更聪明的:

One way would be to assign the view to the element's data, but I'm wondering if I've missed something smarter:

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

(我使用骨干使用jQuery 1.5)。

(I'm using Backbone with jQuery 1.5.)

推荐答案

我刚写了一个jQuery插件这一点。它还使用 。数据() 方法。

I've just written a jQuery plugin for this. It also uses the .data() method.

我已经包裹/代理的骨干查看 setElement 方法所需的数据附加到视图的 $ EL 属性。

I have wrapped / proxied the Backbone View setElement method to attach the required data to the view's $el property.

登记完成后的场景的像这样的背后:

Registration is done behind the scenes like so:

$(myViewsEl).backboneView(myView);

检索:

该插件遍历了DOM层次结构(使用 .closest() ),直到找到需要的数据输入一个元素,即与相关联的视图DOM元素:

Retrieval:

The plugin traverses up the DOM hierarchy (using .closest()) until it finds an element with the required data entry, i.e a DOM element with an associated view:

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

此外,我们可以指定希望获得什么类型的骨干观,继续向上的层次结构,直到我们发现匹配类型的实例:

In addition, we can specify what type of Backbone View we wish to obtain, continuing up the hierarchy until we find an instance of matching type:

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

的jsfiddle示例:

可以发现这里

我希望我的思维正确这里涉及到没有内存泄漏;一个取消链接是,如果 setElement 被称为第二次循环中执行,并自删除视图的元话费的 一个.remove() 。让我知道,如果你有不同的看法。

I hope I am correct in thinking there are no memory leaks involved here; An 'unlink' is performed if setElement is called a second time round, and since removing a view's element calls .remove() by default, which destroys all data as well. Let me know if you think differently.

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

这篇关于Backbone.js的 - 给定一个元素,我怎么认为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆