1

我知道这个问题已经被问过好几次了,但是所有的答案都让我感到困惑,因为我不确定如何让咖啡脚本代码编译成指定的 jquery 代码。

这是我到目前为止所拥有的:

pluginName = 'tagbox'

states = 
  none: 0
  typing: 1
  altering: 2        

defaults =
  editing: true
  tags: []

class Plugin
  constructor: (@element, options) ->
    @options = $.extend {}, defaults, options
    @_defaults = defaults
    @_states = states
    @state = states.none
    @_name = 'tagbox'
    @currentTag = $("<div class='ui-individualtag'></div>")

  # this is the public method I want
  setCurrentTag: (tagText) ->
    @currentTag.text(tagText)

$.fn[pluginName] = (options) ->
  @each ->
    if !$.data(this, "plugin_#{pluginName}")
      $.data(@, "plugin_#{pluginName}", new Plugin(@, options))
)(jQuery, window, document)

然后在另一个脚本中,我希望能够像这样访问 setCurrentTag 方法:

tagbox = $('#tagbox').tagbox()
tagbox.setCurrentTag("hello world")

让我知道它是否有助于在 jquery 中显示它编译成的内容。

4

1 回答 1

2

你的问题是tagbox

tagbox = $('#tagbox').tagbox()

将是一个 jQuery 对象,并且没有setCurrentTag方法。您不想尝试更改它,因为这会破坏通常的 jQuery 链接行为。解决此问题的一种方法是为tagbox插件提供足够的智能来解析其参数,以便您可以传递方法名称:

$('#tagbox').tagbox('setCurrentTag', 'hello world')

这是jQuery-UI采用的方法,所以很多 jQuery 人应该熟悉它。

你需要做的就是修改你$.fn.tagbox的看起来更像这样:

$.fn[pluginName] = (options = {}) ->
  if $.isPlainObject options
    @each ->
      if !$.data(@, "plugin_#{pluginName}")
        $.data(@, "plugin_#{pluginName}", new Plugin(@, options))
  else
    args = Array.prototype.slice.call(arguments);
    @each ->
      p = $.data(@, "plugin_#{pluginName}")
      p[args[0]](args[1])

演示:http: //jsfiddle.net/ambiguous/q2U7d/

需要注意的一些事项:

  1. 我添加了一个默认值 ( (options = {}) ->),这样它options就会一直存在。
  2. 我们可以使用 来检查我们是否有一个选项对象$.isPlainObject,如果没有选项,那么我们可以假设我们正在做一个方法调用。这就是为什么我们想要1中的默认值。
  3. 我们使用Array.prototype.slice.callhack 将类数组转换arguments为真正的数组,以使其更易于使用。我们不必这样做,但如果我们想使用 Array 方法(例如pop)并且无论如何我们需要在回调arguments内部引用外部,它可以避免一些混乱:是上下文敏感的,就像在 (Coffee|Java) 中一样脚本。@eachargumentsthis
于 2012-04-12T20:42:53.003 回答