2012-02-04 36 views
44

Tôi đang đào sâu vào Bootstrap của Twitter và bây giờ muốn thử và thêm một số chức năng vào các plugin, nhưng tôi không thể tìm ra cách để làm như vậy. Sử dụng plugin modal làm ví dụ (http://twitter.github.com/bootstrap/javascript.html#modals), tôi muốn thêm một hàm mới vào plugin có thể được gọi là một phương pháp plugin chuẩn. Gần nhất tôi nghĩ rằng tôi đã đến là với các mã sau đây, nhưng tất cả tôi nhận được khi tôi cố gắng truy cập là chức năng không phải là một phần của đối tượng.Làm thế nào để mở rộng Plugin Twitter Bootstrap

Mọi đề xuất? Đây là những gì tôi đã cố gắng mà có vẻ là gần nhất với những gì tôi cần phải làm:

$.extend($.fn.modal, { 
    showFooterMessage: function (message) { 
     alert("Hey"); 
    } 
}); 

Sau đó, tôi muốn gọi nó là như sau:

$(this).closest(".modal").modal("showFooterMessage"); 

EDIT: OK, tôi đã tìm ra cách thực hiện việc này:

(function ($) { 
    var extensionMethods = { 
     displayFooterMessage: function ($msg) { 
      var args = arguments[0] 
      var that = this; 

      // do stuff here 
     } 
    } 

    $.extend(true, $.fn.modal.Constructor.prototype, extensionMethods); 
})(jQuery); 

Vấn đề với bộ plugin Bootstrap hiện tại là nếu bất kỳ ai muốn mở rộng, không có phương pháp mới nào có thể chấp nhận đối số. Nỗ lực của tôi để "sửa" điều này là thêm sự chấp nhận các đối số trong lời gọi hàm plugin.

$.fn.modal = function (option) { 
    var args = arguments[1] || {}; 
    return this.each(function() { 
     var $this = $(this) 
     , data = $this.data('modal') 
     , options = typeof option == 'object' && option 

     if (!data) $this.data('modal', (data = new Modal(this, options))) 

     if (typeof option == 'string') data[option](args) 
     else data.show() 

    }) // end each 
} // end $.fn.modal 
+5

Nếu chỉnh sửa này có nghĩa là để được một câu trả lời, bạn sẽ có thể gửi nó như một câu trả lời tại . Xin hãy tiếp tục và làm như vậy :) – BoltClock

+0

Dường như bịa đặt câu trả lời cho câu hỏi của tôi;) – AlexGad

+1

Ồ, đừng lo lắng. Nó hoàn toàn bình thường - thậm chí [tôi đã thực hiện nó một lần] (http://stackoverflow.com/questions/5493149/how-do-i-make-a-wpf-window-movable-by-dragging-the-extended- glass-frame) :) – BoltClock

Trả lời

35

Đây là một chủ đề cũ, nhưng tôi chỉ cần thực hiện một số phần mở rộng tùy chỉnh để phương thức sử dụng các mô hình sau:

// save the original function object 
var _super = $.fn.modal; 

// add custom defaults 
$.extend(_super.defaults, { 
    foo: 'bar', 
    john: 'doe' 
}); 

// create a new constructor 
var Modal = function(element, options) { 

    // do custom constructor stuff here 

    // call the original constructor 
    _super.Constructor.apply(this, arguments); 

} 

// extend prototypes and add a super function 
Modal.prototype = $.extend({}, _super.Constructor.prototype, { 
    constructor: Modal, 
    _super: function() { 
     var args = $.makeArray(arguments); 
     _super.Constructor.prototype[args.shift()].apply(this, args); 
    }, 
    show: function() { 

     // do custom method stuff 

     // call the original method 
     this._super('show'); 
    } 
}); 

// override the old initialization with the new constructor 
$.fn.modal = $.extend(function(option) { 

    var args = $.makeArray(arguments), 
     option = args.shift(); 

    return this.each(function() { 

     var $this = $(this); 
     var data = $this.data('modal'), 
      options = $.extend({}, _super.defaults, $this.data(), typeof option == 'object' && option); 

     if (!data) { 
      $this.data('modal', (data = new Modal(this, options))); 
     } 
     if (typeof option == 'string') { 
      data[option].apply(data, args); 
     } 
     else if (options.show) { 
      data.show.apply(data, args); 
     } 
    }); 

}, $.fn.modal); 

Bằng cách này bạn có thể

1) thêm các tùy chọn mặc định của riêng bạn

2) tạo các phương thức mới với các đối số tùy chỉnh và quyền truy cập vào các hàm ban đầu (siêu)

3) thực hiện các công cụ trong hàm tạo trước và/hoặc sau const ban đầu ructor được gọi

+0

David - Tôi sẽ biết ơn nếu bạn có thể xem xét câu hỏi của tôi về cú pháp khởi tạo ghi đè bạn đã sử dụng: http://stackoverflow.com/q/39751235 –

4

Để tham khảo, tôi có một vấn đề tương tự vì vậy tôi "extended" the Typeahead plugin bằng cách thêm và thêm chức năng tôi cần trong chính kịch bản plugin.

Nếu bạn phải thay đổi nguồn, nó không thực sự là tiện ích mở rộng, vì vậy tôi thấy dễ dàng hơn khi đặt tất cả các sửa đổi của tôi ở một nơi.

26

Đối với hồ sơ có một phương pháp đơn giản để ghi đè lên hoặc mở rộng các chức năng hiện có:

var _show = $.fn.modal.Constructor.prototype.show; 

$.fn.modal.Constructor.prototype.show = function() { 
    _show.apply(this, arguments); 
    //Do custom stuff here 
}; 

Không bao gồm lập luận tùy chỉnh, nhưng nó cũng dễ dàng với các phương pháp trên; thay vì sử dụng applyarguments, chỉ định đối số ban đầu cộng với đối số tùy chỉnh trong định nghĩa hàm, sau đó gọi số _show gốc (hoặc bất kỳ giá trị nào) với đối số ban đầu và cuối cùng thực hiện các công cụ khác với đối số mới.

+0

Bằng cách nào đó các phương pháp khác sẽ chạy vào một vòng lặp vô hạn mỗi lần .. cái này hoạt động hoàn hảo! 1 cho đơn giản :) –

+0

Điều này là rất tốt, nhưng không tốt nếu bạn muốn mở rộng các nhà xây dựng (làm những việc về xây dựng, chẳng hạn như thêm bindings/etc.). – prograhammer

+1

@DavidGraham bạn có thể ghi đè lên các nhà xây dựng quá, nó ngay trong mẫu thử nghiệm. Trong ví dụ trên, bạn muốn ghi đè phương thức '$ .fn.modal.Constructor.prototype.constructor'. – Mahn

2

Đối với bất cứ ai tìm cách để làm điều này với Bootstrap 3. Việc bố trí plugin đã thay đổi một chút các tùy chọn mặc định cho tất cả Bootstrap 3 plugins được gắn vào các plugin constructor:

var _super = $.fn.modal; 
$.extend(_super.Constructor.DEFAULTS, { 
     foo: 'bar', 
     john: 'doe' 
}); 
2

+1 cho câu trả lời được chấp nhận trên từ David.Nhưng nếu tôi có thể đơn giản hóa nó hơn một chút, tôi muốn điều chỉnh DEFAULTS mở rộng và $fn.modal mở rộng như vậy:

!function($) { 

    'use strict'; 

    // save the original function object 
    var _super = $.fn.modal; 

    // create a new constructor 
    var Modal = function(element, options) { 

     // do custom constructor stuff here 

     // call the original constructor 
     _super.Constructor.apply(this, arguments); 

    } 

    // add custom defaults 
    Modal.DEFAULTS = $.extend(_super.defaults, { 
     myCustomOption: true 
    }); 

    // extend prototypes and add a super function 
    Modal.prototype = $.extend({}, _super.Constructor.prototype, { 
     constructor: Modal, 
     _super: function() { 
      var args = $.makeArray(arguments); 
      _super.Constructor.prototype[args.shift()].apply(this, args); 
     }, 
     show: function() { 

      // do custom method stuff 

      // call the original method 
      this._super('show'); 
     }, 
     myCustomMethod: function() { 
      alert('new feature!'); 
     } 
    }); 

    // Copied exactly from Bootstrap 3 (as of Modal.VERSION = '3.3.5') 
    // Notice: You can copy & paste it exactly, no differences! 
    function Plugin(option, _relatedTarget) { 
     return this.each(function() { 
      var $this = $(this) 
      var data = $this.data('bs.modal') 
      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) 

      if (!data) $this.data('bs.modal', (data = new Modal(this, options))) 
      if (typeof option == 'string') data[option](_relatedTarget) 
      else if (options.show) data.show(_relatedTarget) 
     }) 
    } 

    // override the old initialization with the new constructor 
    $.fn.modal = $.extend(Plugin, $.fn.modal); 

}(jQuery); 
+0

Theo đề xuất của @benembery, các tùy chọn mặc định được gắn vào không gian tên Constructor. Đối với giải pháp này, tôi nghĩ các giá trị mặc định tùy chỉnh cần phải là // add custom defaults Modal.DEFAULTS = $.extend(_super.Constructor.DEFAULTS, { myCustomOption: true }); jakxnz

Các vấn đề liên quan