如何通过backbone.js打印'this'列表项的文本?

时间:2012-09-04 05:25:23

标签: javascript backbone.js backbone-views

我是Backbone.js的新手。我在这个keyworks上遇到了一些问题。我有一个Backbone视图打击:

 var print = Backbone.View.extend({
    el : $('ul li.newItem'),  
    events : { 'click li.newItem':'printText'},
    initialize:function(){ 
      _.bind(printText,this);  // does 'this' refer to the li.newItem ?
      alert(1233); // init does't work.
    },
    printText : function(){
      //I wanna print the hello world text each list item when clicked.
    }
  });

 var print = new print();  

以下是我的演示:http://jsbin.com/evoqef/3/edit

2 个答案:

答案 0 :(得分:1)

您有两个问题导致initialize无法正常工作:

  1. 范围内没有printText
  2. _.bind_.bindAll表现不同。
  3. 第一个很容易修复,您想使用this.printText,而不仅仅是printText

    _.bind将单个函数绑定到this并将返回绑定函数;另一方面,_.bindAll将几个命名函数绑定到this,并将绑定函数附加到指定的this。所以,这样做:

    _.bind(printText, this);
    
    当你丢弃绑定函数时,

    没有做任何有用的事情。你想要这样做:

    this.printText = _.bind(this.printText, this);
    

    或者更常见的是在Backbone应用中,您使用_.bindAll

    _.bindAll(this, 'printText');
    

    现在,您的initialize功能正常,this内部printText正确,我们可以继续修复printText。我想你要从被点击的<li>中提取文本;你可以这样做:

    printText: function(ev) {
        console.log($(ev.target).text());
    }
    

    但这仍然不起作用,我们不得不想知道这里发生了什么。好吧,Backbone将事件绑定到视图的el,所以让我们看一下:

    var print = Backbone.View.extend({
        el : $('ul li.newItem'),
        //...
    

    Backbone.View.extend运行时,DOM中不会有任何li.newItem个元素,因此您不会在该视图中获得有用的el。这里通常的方法是有一个看起来像这样的视图:

    var Print = Backbone.View.extend({
        tagName: 'li',
        events: {
            'click': 'printText'
        },
        render: function() {
            this.$el.text('Hello world ' + this.options.i);
            return this;
        },
        printText: function(e){
            console.log($(e.target).text());
        }
    });
    

    我们将tagName设置为'li',然后让Backbone自行创建<li>。然后我们将计数器值作为参数传递给Print视图,当我们说this.options.i时,Backbone将负责将参数保留在new Print({ i: ... })

    现在我们只需调整addItem中的ListView方法即可创建新Print并将其添加到<ul>

    addItem: function(){
        this.counter++;
        var v = new Print({ i: this.counter });
        this.$('ul').append(v.render().el);
    }
    

    更新了演示:http://jsbin.com/evoqef/10/edit

    我还做了一些其他改动:

    1. 使用this.$el代替$(this.el),无需创建已有的内容。
    2. 使用this.$()代替$('ul', this.el),结果相同,但this.$()不会隐藏$()函数调用结束时的上下文,而this.$()是在Backbone中更具惯用性。

答案 1 :(得分:0)

_.bind(printText, this);

printText超出了init函数的范围。 this,因为你的第二个参数代表print Backbone.View。

你可以这样做:

_.bind(this.printText, this);

并且可能摆脱init()错误。但是你可以在printText中使用this,无论如何它都代表你的视图。

printText: function() {
    console.log(this);  // this represents your view
}