简体   繁体   English

尝试在Fancybox回调中调用CoffeeScript方法时的作用域问题

[英]Scoping issue when attempting to call CoffeeScript method inside Fancybox callback

I have the following CoffeeScript module named Course. 我有以下名为Course的CoffeeScript模块。 I have a small piece of code which I would like to re-use, I have created a method called preSelectItemSize . 我有一小段代码要重用,我创建了一个名为preSelectItemSize的方法。

I would like to call this method when init is called and also within the afterShow Fancybox callback. 我想在调用init时以及在afterShow Fancybox回调中调用此方法。 The following code works , but it don't believe it is correct to use the module name and I should be using the @ reference to "this" instead. 以下代码有效 ,但是使用模块名称并不正确,我应该使用@引用“ this”。

What am I doing wrong? 我究竟做错了什么? (Code snippet reduced for brevity) (为简洁起见,减少了代码段)

$ = window.jQuery = require("jquery")
Course =

  init: ->

    $('.js-product-overlay').on 'click', (e) =>
      @viewProductClickHandler(e, MediaDetection)

    @preSelectItemSize()

  viewProductClickHandler: (e, mediaDetection) =>

    $('.js-product-overlay').fancybox({
      href: wishlist_overlay_href
      maxWidth: '775px'
      minHeight: '495px'
      autoCenter: '!isTouch'
      height: 'auto'
      scrolling: true
      fitToView: false
      autoSize: false
      padding: 0
      tpl:
        closeBtn: '<a class="fancybox-item modal__close fancybox-close" href="javascript:;">Close</a>'
      afterShow: ->
        $('.js-fancybox-close').on 'click', (e) ->
          e.preventDefault()
          $.fancybox.close()

        Course.preSelectItemSize()
    })

  preSelectItemSize: ->
    itemId = $('.modal__product-info').attr('data-item-id')
    $('#size-' + itemId).click()

module.exports = Course

I think your real problem is that you're using a simple object literal rather than a class so => doesn't quite behave the way you expect it to and you're left referring to Course by name. 我认为您的真正问题是您使用的是简单的对象文字而不是类,所以=>并不完全符合您的期望,因此您将按名称来指代Course

If we look at a simplified example: 如果我们看一个简化的例子:

o =
  m: =>

we can see what's going on by looking at the JavaScript that gets produced: 我们可以通过查看生成的JavaScript来了解发生了什么:

var o;
o = {
  m: (function(_this) {
    return function() {};
  })(this)
};

Because we have just a simple data structure (ie a plain old object literal), there is no constructor to bind m to any instance and it behaves as though you said: 因为我们只有一个简单的数据结构(即普通的旧对象文字),所以没有构造函数将m绑定到任何实例,并且其行为就像您说的那样:

m = =>
o = m: m

so any function properties of o (or Course in your case) are just plain old properties that happen to be functions, they're not really methods. 所以o任何函数属性(或您的Course )都是碰巧是函数的普通旧属性,它们并不是真正的方法。

You could drop all the fat-arrows and refer to Course by name or you could switch to a class so that there is an instance for CoffeeScript to bind things to: 您可以删除所有粗箭头,并按名称引用Course ,也可以切换到一个类,以便CoffeeScript有一个实例将其绑定到:

class Course
  #...
module.exports = new Course

The following works by changing the viewProductClickHandler to a thin arrow and changing the afterShow callback to a fat arrow: 通过将viewProductClickHandler更改为细箭头,并将afterShow回调更改为afterShow箭头,可以进行以下操作:

Course =

  init: ->

    $('.js-product-overlay').on 'click', (e) =>
      @viewProductClickHandler(e, MediaDetection)

    @preSelectItemSize()

  viewProductClickHandler: (e, mediaDetection) ->

    $('.js-product-overlay').fancybox({
      href: wishlist_overlay_href
      maxWidth: '775px'
      minHeight: '495px'
      autoCenter: '!isTouch'
      height: 'auto'
      scrolling: true
      fitToView: false
      autoSize: false
      padding: 0
      tpl:
        closeBtn: '<a class="fancybox-item modal__close fancybox-close" href="javascript:;">Close</a>'
      afterShow: =>
        $('.js-fancybox-close').on 'click', (e) ->
          e.preventDefault()
          $.fancybox.close()

        @preSelectItemSize()
    })

  preSelectItemSize: ->
    alert "preSelectItemSize executed."
    itemId = $('.modal__product-info').attr('data-item-id')
    $("#size-#{itemId}").click()

Course.init()

See fiddle for example of working code: https://jsfiddle.net/L5u31Lzr/1/ 有关工作代码的示例,请参阅小提琴: https : //jsfiddle.net/L5u31Lzr/1/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM