Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
backbone.js-通过单击事件访问模型_Backbone.js - Fatal编程技术网

backbone.js-通过单击事件访问模型

backbone.js-通过单击事件访问模型,backbone.js,Backbone.js,我有一个包含CellModels的CellCollection的BoardView。我从数据库中获取集合,然后创建CellView 在我尝试通过BoardView上的点击事件访问CellModel之前,这一切都很顺利。我根本无法了解底层模型。。。只有景色。有办法做到这一点吗 我已尝试在下面包含相关代码: CellModel = Backbone.Model.extend({}); CellCollection = Backbone.Collection.extend({ model :

我有一个包含CellModels的CellCollection的BoardView。我从数据库中获取集合,然后创建CellView

在我尝试通过BoardView上的点击事件访问CellModel之前,这一切都很顺利。我根本无法了解底层模型。。。只有景色。有办法做到这一点吗

我已尝试在下面包含相关代码:

CellModel = Backbone.Model.extend({});

CellCollection = Backbone.Collection.extend({
    model : CellModel
});

CellView = Backbone.View.extend({
    className : 'cell',
});

BoardView = Backbone.View.extend({
    this.model.cells = new CellCollection();

    render : function() {
        this.cellList    = this.$('.cells');
        return this;
    },

    allCells : function(cells) {
        this.cellList.html('');
        this.model.cells.each(this.addCell);
        return this;
    },

    addCell : function(cell) {
        var view = new Views.CellView({
            model : cell
        }).render();

        this.cellList.append(view.el);
    },

    events : {
        'click .cell' : 'analyzeCellClick',
    },

    analyzeCellClick : function(e) {
        // ?????????
    }
});

我需要在BoardView(而不是CellView)上单击“发生”,因为它涉及特定于电路板的逻辑。

我可以想到至少两种方法,您可以在这里使用:

  • 在初始化时将BoardView传递给CellView,然后在CellView中处理事件:

    var CellView = Backbone.View.extend({
        className : 'cell',
    
        initialize: function(opts) {
            this.parent = opts.parent
        },
    
        events : {
            'click' : 'analyzeCellClick',
        },
    
        analyzeCellClick : function() {
            // pass the relevant CellModel to the BoardView
            this.parent.analyzeCellClick(this.model);
        }
    });
    
    var BoardView = Backbone.View.extend({
        // ...
    
        addCell : function(cell) {
            var view = new Views.CellView({
                model : cell,
                parent : this
            }).render();
    
            this.cellList.append(view.el);
        },
    
        analyzeCellClick : function(cell) {
            // do something with cell
        }
    });
    
    这是可行的,但我不希望视图调用彼此的方法,因为这样会使它们更紧密地耦合

  • 渲染时将CellModel id附加到DOM:

    var CellView = Backbone.View.extend({
        className : 'cell',
    
        render: function() {
            $(this.el).data('cellId', this.model.id)
            // I assume you're doing other render stuff here as well
        }
    });
    
    var BoardView = Backbone.View.extend({
        // ...
    
        analyzeCellClick : function(evt) {
            var cellId = $(evt.target).data('cellId'),
                cell = this.model.cells.get(cellId);
            // do something with cell
        }
    });
    
    这可能有点干净,因为它避免了上面提到的紧密耦合,但我认为这两种方法都可以


  • 好问题!我认为最好的解决办法是实施

    EventBusakaEventDispatcher

    协调应用程序不同区域之间的所有事件

    走这条路看起来是干净的、松散耦合的、易于实现的、可扩展的,这实际上是主干文档建议的,请参阅

    请阅读更多关于这个话题的内容,因为(尽管我努力了)我自己的解释对我来说似乎有些平庸

    五步说明:

  • 在main或其他地方创建一个EventBus作为util,并包含/要求它

  • 向其中添加一个或多个回调文件夹

  • 将触发器添加到childView的Eventlistener(此处:CellView)

  • 将侦听器添加到parentView的Initialize函数(此处:BoardView)

  • 在parentView中定义相应的回调(并将其添加到u.bindAll中)


  • 我会让
    CellView
    处理点击事件,但它只会触发主干事件:

    var CellView = Backbone.View.extend({
        className : 'cell',
    
        initialize: function() {
            _.bindAll(this, 'analyzeCellClick');
        }
    
        events : {
            'click' : 'analyzeCellClick',
        },
    
        analyzeCellClick : function() {
            this.trigger('cellClicked', this.model);
        }
    });
    
    var BoardView = Backbone.View.extend({
        // ...
    
        addCell : function(cell) {
            var view = new Views.CellView({
                model : cell
            }).render();
    
            this.cellList.append(view.el);
            view.bind('cellClicked', function(cell) {
                  this.analyzeCellClick(cell);
                };
        },
    
        analyzeCellClick : function(cell) {
            // do something with cell
        }
    });
    

    在这里。两种解决方案都完美无瑕。。。而且#1对我来说是完美的。非常感谢。太好了-如果你对答案感到满意,你可以通过点击分数下方的复选框来接受答案:)。在我看来,解决方案2不是一个好主意。主干网的全部功能是从服务器获取数据并在客户机视图中呈现,而不是从视图获取数据并发回。这是可行的,但不是一个好方法。很好的解决方案。但是代码中很少有错误。1.view.bind('cellClicked'this.analyzeCellClick)2。请尝试一下我们在analyzeCellClick中获得的上下文。这将是值得考虑的,因为此方法是由cellview触发的,所以使用闭包或Function.bind。这种方法似乎更符合我对主干如何工作的理解。还是我错了?
     dispatcher.CELL_CLICK = 'cellClicked'
    
     dispatcher.trigger(dispatcher.CELL_CLICK , this.model);
    
     eventBus.on(eventBus.CARD_CLICK, this.cardClick);
    
     cellClicked: function(model) {
     // do what you want with your data here
     console.log(model.get('someFnOrAttribute')
     }
    
    var CellView = Backbone.View.extend({
        className : 'cell',
    
        initialize: function() {
            _.bindAll(this, 'analyzeCellClick');
        }
    
        events : {
            'click' : 'analyzeCellClick',
        },
    
        analyzeCellClick : function() {
            this.trigger('cellClicked', this.model);
        }
    });
    
    var BoardView = Backbone.View.extend({
        // ...
    
        addCell : function(cell) {
            var view = new Views.CellView({
                model : cell
            }).render();
    
            this.cellList.append(view.el);
            view.bind('cellClicked', function(cell) {
                  this.analyzeCellClick(cell);
                };
        },
    
        analyzeCellClick : function(cell) {
            // do something with cell
        }
    });