2011-09-08 87 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 = [];