2013-02-28 32 views
41

有關流星中的模板的事件處理程序的上下文(帶Handlebars)的快速問題。流星模板事件處理程序中的「this」的上下文(使用Handlebars進行模板化)

  • 在上模板實例文檔(http://docs.meteor.com/#template_inst)的部分中,提到「模板實例對象被發現作爲此在所創建的,呈現的值,並破壞模板回調和作爲參數傳遞給事件處理器
  • 在模板部分(http://docs.meteor.com/#templates)它說:」 最後,你可以使用事件聲明的模板函數來設置事件處理程序表,格式在事件映射被記錄在案。的這參數給事件處理程序會觸發事件的元素的數據上下文

好了,這只是部分正確讓我們用從文檔的例子:

<template name="scores"> 
    {{#each player}} 
    {{> playerScore}} 
    {{/each}} 
</template> 

<template name="playerScore"> 
    <div>{{name}}: {{score}} 
    <span class="givePoints">Give points</span> 
    </div> 
</template 
Template.playerScore.events({ 
    'click .givePoints': function() { 
    Users.update({_id: this._id}, {$inc: {score: 2}}); 
    }); 

這裏了‘‘點擊.givePoints’事件,這個’背景下確實模板。例如playerScore的讓我們修改HTML:

<template name="scores"> 
    <span class="click-me">Y U NO click me?<span> 
    {{#each player}} 
    {{> playerScore}} 
    {{/each}} 
</template> 

<template name="playerScore"> 
    <div>{{name}}: {{score}} 
    <span class="givePoints">Give points</span> 
    </div> 
</template> 

...然後添加一個事件處理程序。點擊,我的分數模板:

Template.scores.events({ 
    'click .click-me': function() { 
    console.log(this); 
    } 
}); 

現在,如果你點擊跨度,你會得到什麼記錄? Window對象!我期望得到什麼?模板對象!或者可能是數據上下文,但它不是。但是,在回調中(例如Template.scores.rendered = function(){...}),「this」的上下文始終是模板實例。

我想我真正的問題是:這事做的之間

  • 一個bug在車把,流星或地方?
  • 模板上的文檔略有不完整?
  • 我完全誤解了文檔,或者沒有理解關於流星或Handlebars的基本內容 ?

謝謝!

+6

這是一個正確的問題。我總是使用'function(event,template)',然後通過'template.data'訪問事件中的數據。 – Twark 2013-02-28 16:24:44

+0

希望我可以upvote兩次 – Ruby 2015-06-29 18:21:56

+0

@ТаняТ。你可以把問題標記爲最喜歡的,就像我做的那樣;-) – think01 2015-09-03 09:38:02

回答

27

這部影片介紹的概念:

http://www.eventedmind.com/posts/meteor-spark-data-annotation-and-data-contexts

直接回答你的問題:

的thisArg的事件處理程序裏面應該指向一個數據上下文。但有時數據上下文是undefined。當您在JavaScript中使用Function.prototype.call(thisArg, ...)時,如果thisArg未定義(例如,一個dataContext未定義),瀏覽器將設置this等於窗口。所以,文檔本身不是錯誤,但事件處理代碼沒有防範未定義數據上下文的可能性。我猜這將在短期內得到修復。

那麼,什麼產生模板的數據上下文?通常你的根模板甚至沒有數據上下文。換句話說,模板函數在沒有對象的情況下被調用。但是,如果使用{{#with塊幫助器或{{#each迭代器,則將爲列表中的每個項目創建數據上下文,或者在幫助器(對象)的情況下創建數據上下文。

實施例:

var context = {}; 

<template name="withHelper"> 
    {{#with context}} 
    // data context is the context object 
    {{/with}} 
</template> 

var list = [ {name: "one"}, {name: "two"} ]; 

<template name="list"> 
    {{#each list}} 
    {{ > listItem }} // data context set to the list item object 
    {{/each}} 
</template> 
+0

釘了它,謝謝! – 2013-03-01 09:37:56

+0

如果數據上下文未定義,數據上下文設置爲'window'已在最新版本的Meteor中修復。所以,現在在事件處理程序中''this'總是指向一個對象,無論是數據上下文還是空對象(如果沒有數據上下文)。 – cmather 2013-03-16 02:00:16

+1

是的血腥是的!!!!! – 2013-03-18 12:58:51

13

函數中的第一個參數是事件。所以你可以使用事件的目標來抓住你的元素。

Template.scores.events({ 
    'click .click-me': function (event, template) { 
    console.log(event.target); 
    $(event.target).text("O but I did!"); 
    } 
}); 
+2

謝謝布蘭登。這確實是抓住元素的一種方式(儘管我通常會使用currentTarget)。但它不回答我的問題:錯誤,文檔或我? – 2013-02-28 18:19:45

+2

我會說文檔。因爲流星仍然是預發佈。 Docs可能是保持最新並且完全包容的最困難的事情。在這些情況下,我只是開始向函數添加參數,然後控制檯記錄它們。例如函數(param1,param2,param3){console.log(param1);的console.log(參數2); console.log(param3);} – 2013-02-28 18:29:04

+1

您可以使用console.log(參數)一次全部獲取它們。 – 2015-05-23 13:58:25