2016-01-08 1 views
0

J'ai le module CoffeeScript suivant appelé Course. J'ai un petit morceau de code que je voudrais réutiliser, j'ai créé une méthode appelée preSelectItemSize.Problème de portée lors de l'appel de la méthode CoffeeScript dans le rappel Fancybox

Je voudrais appeler cette méthode lorsque init est appelée et également dans le rappel Fancybox afterShow. Le code suivant fonctionne, mais il ne croit pas qu'il est correct d'utiliser le nom du module et je devrais utiliser la référence @ à "this" à la place.

Qu'est-ce que je fais mal? (Extrait de code réduit par souci de concision)

$ = 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 
+1

Voulez-vous juste 'afterShow: =>' au lieu de 'afterShow: ->'? –

+0

@muistooshort Non, j'ai d'abord utilisé la "grosse flèche" '=> 1', mais cela ne fonctionne pas. Je l'ai juste réessayé et ai '_this.preSelectItemSize n'est pas une fonction – crmpicco

+0

Juste, parce que vous n'avez pas de classe, vous avez juste un objet littéral, manqué cela. –

Répondre

0

Les travaux suivants en changeant le viewProductClickHandler à une fine flèche et en changeant le rappel afterShow à une matière grasse flèche:

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

Voir violon par exemple du code de travail: https://jsfiddle.net/L5u31Lzr/1/

1

Je pense que votre vrai problème est que vous utilisez un objet littéral simple plutôt que d'une classe si => ne se comporte pas tout à fait la façon dont vous vous attendez à et vous êtes gauche se référant à Course par le nom.

Si nous regardons un exemple simplifié:

o = 
    m: => 

nous pouvons voir ce qui se passe en regardant le JavaScript qui obtient produit:

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

Parce que nous avons juste une structure de données simple (c'est-à-dire un vieux littéral d'objet simple), il n'y a aucun constructeur à lier m à n'importe quelle instance et il se comporte comme si vous avez dit:

m = => 
o = m: m 

donc toutes les propriétés de fonction de o (ou Course dans votre cas) sont simplement de vieilles propriétés qui se trouvent être des fonctions, ce ne sont pas vraiment des méthodes.

Vous pouvez laisser tomber toutes les flèches de graisse et se référer à Course par nom ou vous pouvez passer à une classe pour qu'il y ait une instance pour CoffeeScript de lier les choses à:

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

L'utilisation d'un littéral d'objet est un modèle utilisé dans tout le système, donc je casserais le modèle si je le changeais en classe. N'y a-t-il pas d'autre moyen que je peux appeler cette méthode sans refactoring à une classe? – crmpicco