簡體   English   中英

Backbone.js - 給定一個元素,我如何獲得視圖?

[英]Backbone.js - Given an element, how do I get the view?

我創建了一堆Backbone.js視圖。 每個視圖都有一個關聯元素( view.el )。

給定頁面上的元素 - 視圖的上下文 - 獲取元素視圖的最佳方法是什么?

例如,假設某些事件影響頁面上的一堆元素,並且我想在與受影響元素關聯的每個視圖上調用方法。

一種方法是將視圖分配給元素的數據,但我想知道我是否錯過了更聰明的東西:

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

(我正在使用Backbone和jQuery 1.5。)

我剛剛為此編寫了一個jQuery插件。 它還使用.data()方法。

注冊:

我已經包裝/代理了Backbone View setElement方法,以將所需數據附加到視圖的$el屬性。

注冊是在幕后完成的,如下所示:

$(myViewsEl).backboneView(myView);

恢復:

插件遍歷DOM層次結構(使用.closest() ),直到找到具有所需數據條目的元素,即具有關聯視圖的DOM元素:

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

另外,我們可以指定我們希望獲得哪種類型的Backbone View,繼續層次結構,直到找到匹配類型的實例:

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

JSFiddle示例:

可以在這里找到。

筆記:

我希望我認為這里沒有內存泄漏是正確的; 如果第二次調用setElement則執行'unlink',並且因為刪除視圖的元素默認調用.remove() ,這也會破壞所有數據。 如果您有不同的想法,請告訴我。

插件代碼:

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

每個視圖都可以注冊DOM事件。 因此,具有您感興趣的元素類型的每個視圖都應該注冊DOM事件,然后分配一個事件響應函數來執行您想要的操作。 如果您需要干預,請使用mixin技術混合功能。

我想這個解決方案可能比你最初想象的要容易。 只是讓視圖完成他們打算做的工作。

您可以維護使用元素作為鍵的視圖哈希(字典)並返回視圖(或視圖)。

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

我一直在使用受Ed的解決方案啟發的方法,但它不需要使用jQuery。 它做了兩件事:

  1. 它在所有視圖的根元素上設置屬性data-backbone-view 在調試器中查看DOM樹時,這很方便。 您可以立即查看哪些元素與視圖相關聯。 您還可以使用CSS選擇器[data-backbone-view]來查找作為Backbone視圖根源的元素。

  2. 它為視圖的每個根元素添加了backboneView屬性。 然后可以通過查看DOM元素的屬性從DOM元素到視圖。

我只在我調試時打開它。 這是代碼:

var originalSetElement = Bb.View.prototype.setElement;

Bb.View.prototype.setElement = function setElement(element) {
  if (this.el && this.el !== element) {
    delete this.el.backboneView;
  }

  element.backboneView = this;
  element.setAttribute("data-backbone-view", "true");

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

由於每個視圖都有對其顯示的模型的引用,我要做的是將模型的id分配給視圖的相關元素(希望不受外部事件的更改影響)。 還要確保模型具有對其視圖的引用。 然后將這些模型存儲在Backbone集合中。

使用此設置,一旦元素發生某些事情,您可以使用元素id從上面創建的Backbone集合中檢索相應的模型,然后此模型將為您提供視圖參考。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM