2011-09-08 83 views
4

我正在学习JavaScript,并以我想了解更多关于jQuery的方式。我已经创造了JS一个非常简单的“形式控制器”,所以当我创建传递形式参数的对象时,它得到的事件有线和劫持提交:jQuery扩展和关闭

var FormController = function (form) { 

    // private field 
    var _form = $(form); 
    var _url = _form.attr('action'); 
    var _isValid = false; 

    $(form).submit(function (e) { 
     submitForm(); 
     e.preventDefault(); 
    }); 

    var disableAll = function() { 
     _form.find('select,input,textarea').attr('disabled', 'disabled') 
    }; 

    var enableAll = function() { 
     _form.find('select,input,textarea').removeAttr('disabled') 
    }; 

    var submitForm = function() { 

     disableAll(); 
     _isValid = true; 

     if (_isValid) { 
      $.ajax({ 
       url: _url, 
       type: 'POST', 
       success: function (data, textStatus, jqXHR) { 
        enableAll(); 
        var obj = jQuery.parseJSON(jqXHR.responseText); 
        print(data.Result ? data.Result : "[No Result]"); 
        print(textStatus.toString()); 
       }, 
       error: function (data, textStatus, jqXHR) { 
        print(textStatus); 
        _form.css('border', '1px solid Red'); 
        enableAll(); 
       } 
      }); 
     } 
    }; 

    // public fields and functions 
    return { 
     getIsValid: function() { return _isValid; }, 
     submit: function() { return submitForm(); } 
    }; 
}; 

它按预期工作。现在,我想创建一个jQuery扩展,这样我就可以申请该对象的结果:

$.fn.formController = function() { 
    return this.each(function (i, item) { 
     new FormController(item); 
    }); 
}; 

我也工作正常,但是......将在GC收集对象?或者因为这些事件是有线的,它会被视为参考?

现在,我想保留我的控制器的实例可用,所以我可以在创建后操作它们,例如调用方法。这样的事情:

$('#myForm').formController('submit'); 

我已经尝试了几种方法来做到这一点,但我无法得到它。我试图用一个跟踪项目的对象来放置一个闭包,但是我只是因为“这个”而陷入混乱。

这样做的正确方法是什么?而且我认为,即使它有效,我迄今所做的一切都可能是错误的。

谢谢。

UPDATE

很抱歉,如果这个问题还不够清楚。我的目标是我可以做到的一种方式:$('#myForm').formController('submit');,然后funcion会找到与该HTML对象关联的“FormController”对象,并调用这个“submit”成员。

我要实现的是这样的:

$.fn.formController = function (name) { 

    if(!document._items) 
     document._items = []; 

    if (name) { 
     return this.each(function (i, item) { 
      var id = $(item).data('form-controller'); 

      if (id) { 
       var fc = document._items[id]; 
       var member = fc[name]; 
       if (member) { 
        if (typeof member == 'function') 
         member(); 
       } 
      } 
     }); 
    } 
    else {  
     return this.each(function (i, item) { 
      var id = document._items.push(new FormController(item)) - 1; 
      $(item).data('form-controller', id.toString()); 
     }); 
    } 
}; 

这种方法的问题是,我让一个集合作为全局对象,而我要的是让内部。我尝试过使用闭包,但是我只遇到了“this”(指向DOMwindow)或“_items”变量为空的问题。

什么是正确的方法来解决这个问题?

回答

2

您可以使用jQuery UI的小部件工厂,为您提供了功能外的开箱:

$.widget("vtortola.formcontroller", { 
    _create: function() { 
     // Use `this.element` to initialize the element. 
     // You can also use this.options to get the options object that was passed. 
    }, 
    _destroy: function() { 
     // You can unbind events here to remove references from the DOM, so is'll get 
     // deleted by the garbage collector. 
    }, 
    submit: function() { /* ... */ } 
}); 

// Example 
$('#form').formcontroller({foo: 123}); // Calls `_create()` with the supplied options 
$('#form').formcontroller('submit'); // Calls the `submit` method 

小工厂工厂还为您提供选项setter/getters,默认选项和其他很酷的东西。有关更多详细信息,请参见the official docstutorial at bililite。如果你不使用jQuery UI作为其他的东西,你可以使用widget factory code作为一个独立的,它不依赖于jQuery UI的其他部分。

如果你喜欢它,而不使用jQuery UI的widget工厂,你可以直接在.data()(这也是widget工厂所做的)存储这些对象,不需要保存它们的集合并手动跟踪它。你的代码将沿着这样的方向:

+0

谢谢。第二个例子不起作用,首先是因为在“FromController”中有一个输入错误:D但是也是因为“arguments [0]”总是“0”,它不包含'submit'项。任何想法为什么会发生这种情况? – vtortola

+1

哦,'arguments'指的是传递给'each()'函数的参数。我更新了代码来解决这个问题。 – shesek

+1

再次更新了代码,它缺少名称空间的小部件名称 – shesek

0

使用

(function($){ 
    $.fn.formController = function(parameter1, parameter2){ 
      //this = #myForm 
    } 
)(jQuery); 

和阅读this

+0

嗯,我感兴趣的是在该方法的内部,例如,或其他技术来实现我想要的。 – vtortola

+0

@vtortola:我没有得到你,你想在里面做什么? – genesis

+0

好吧,正如你所看到的,当我调用“$('#theForm')。formController()”时,我创建了一个对象“FormController”。我想要的是之后从该对象调用方法的方法。例如,“$('#theForm')。formController('submit')”。为此,我需要在内部保留一个包含“FormController”所有实例的哈希表,但我不知道我可以使用哪个密钥,并且我不知道将集合放在哪里,或者如何去做。 – vtortola

0

我还试图建立一个集合函数本身的性质。

它的工作原理,但我不知道如何正确/合适的,它是:d

$.fn.formController = function (name) { 

    if (name) { 
     return this.each(function (i, item) { 
      var id = $(item).data('form-controller'); 

      if (id) { 
       var fc = $.fn.formController.Items[id]; 
       print('get: ' + id + ' ' + (fc?'found':'not found')); 
       var member = fc[name]; 
       if (member) { 
        if (typeof member == 'function') 
         member(); 
       } 
      } 
     }); 
    } 
    else { 

     return this.each(function (i, item) { 
      var id = $.fn.formController.Items.push(new FormController(item)) - 1; 
      print('add: ' + id); 
      $(item).data('form-controller', id.toString()); 
     }); 
    } 
}; 
$.fn.formController.Items = [];