2010-06-26 26 views
10

Hi Tôi đang cố gắng để tác giả một plugin jQuery và tôi cần phải có phương pháp tiếp cận đến các yếu tố sau khi được khởi tạo như loại đối tượng, ví dụ:phương pháp Tạo on the fly

$('.list').list({some options}); //This initializes .list as a list 

//now I want it to have certain methods like: 
$('.list').find('List item'); //does some logic that I need 

Tôi đã thử với

$.fn.list = function (options) { 
    return this.each(function() { 
     // some code here 
     this.find = function(test) { 
      //function logic 
     } 
    } 
} 

và một số lần thử khác nhau khác, tôi không thể tìm ra cách thực hiện.

EDIT:

Tôi sẽ cố gắng giải thích điều này tốt hơn.

Tôi đang cố gắng biến một bảng thành danh sách, về cơ bản giống như danh sách trên máy tính có tiêu đề cột và các mục có thể sắp xếp và mọi thứ không hợp lệ. Bạn bắt đầu bảng với một lệnh như

$(this).list({ 
    data: [{id: 1, name:'My First List Item', date:'2010/06/26'}, {id:2, name:'Second', date:'2010/05/20'}] 
}); 

.list sẽ làm cho <tbody> sắp xếp được và làm một vài nhiệm vụ ban đầu khác, sau đó thêm các phương pháp sau để các yếu tố:
.findItem(condition) sẽ cho phép bạn để tìm một mục nhất định bằng cách một điều kiện (như findItem('name == "Second"')
.list(condition) sẽ liệt kê tất cả các mục phù hợp với một điều kiện nhất định
.sort(key) sẽ sắp xếp tất cả các mục bằng một chìa khóa trao
, vv

Cách tốt nhất để thực hiện việc này là gì?

+1

Bạn có thể cung cấp thêm một chút ví dụ không? Thật khó để nói những gì bạn đang sau ... và ['.find()'] (http://api.jquery.com/find/) đã được thực hiện :) –

+1

có thể trùng lặp của [Làm thế nào để tạo một jQuery plugin với phương pháp?] (http://stackoverflow.com/questions/1117086/how-to-create-a-jquery-plugin-with-methods) – redsquare

+0

tiêu đề là gây hiểu lầm, đây không phải là phương pháp tạo ra trên bay. – Anurag

Trả lời

2

tôi tìm thấy giải pháp này ở đây: http://www.virgentech.com/blog/2009/10/building-object-oriented-jquery-plugin.html

Điều này dường như làm chính xác những gì tôi cần.

(function($) { 
    var TaskList = function(element, options) 
    { 
     var $elem = $(element); 
     var options = $.extend({ 
      tasks: [], 
      folders: [] 
     }, options || {}); 

     this.changed = false; 
     this.selected = {}; 

     $elem.sortable({ 
      revert: true, 
      opacity: 0.5 
     }); 

     this.findTask = function(test, look) { 
      var results = []; 

      for (var i = 0,l = options.tasks.length; i < l; i++) 
      { 
       var t = options['tasks'][i]; 
       if (eval(test)) 
       { 
        results.push(options.tasks[i]); 
       } 
      } 
      return results; 
     } 

     var debug = function(msg) { 
      if (window.console) { 
       console.log(msg); 
      } 
     } 
    } 

    $.fn.taskList = function(options) 
    { 
     return this.each(function() { 
      var element = $(this); 

      if (element.data('taskList')) { return; } 

      var taskList = new TaskList(this, options); 

      element.data('taskList', taskList); 

     }); 
    } 

})(jQuery); 

Sau đó, tôi có

$('.task-list-table').taskList({ 
     tasks: eval('(<?php echo mysql_real_escape_string(json_encode($tasks)); ?>)'), 
     folders: eval('(<?php echo mysql_real_escape_string(json_encode($folders)); ?>)') 
    }); 
    var taskList = $('.task-list-table').data('taskList'); 

và tôi có thể sử dụng taskList.findTask(condition);

Và kể từ khi các nhà xây dựng có $elem Tôi cũng có thể chỉnh sửa dụ jQuery cho các phương pháp như list(condition) vv Điều này hoạt động hoàn hảo.

+0

+1 - Tôi thích phương pháp này. – Anurag

0

this.each không cần thiết. Điều này nên làm:

$.fn.list = function (options) { 
    this.find = function(test) { 
     //function logic 
    }; 
    return this; 
}; 

Lưu ý rằng bạn sẽ ghi đè phương pháp gốc của phương pháp find của jQuery và làm như vậy không được khuyến khích.


Ngoài ra, với giá trị của nó, tôi không nghĩ đây là một ý tưởng hay. Các cá thể jQuery được giả định chỉ có các phương thức được thừa kế từ đối tượng nguyên mẫu của jQuery và như vậy tôi cảm thấy những gì bạn muốn làm sẽ không nhất quán với hành vi jQuery-plugin được chấp nhận chung - tức là trả về đối tượng this (cá thể jQuery).

+0

Trong khi tôi đồng ý * thường *, điều này không phải luôn luôn như vậy, một ví dụ chính tôi có thể nghĩ là plugin hợp lệ ... tất cả đều phụ thuộc vào nhu cầu của bạn là. –

+0

Tôi đã thử làm điều đó (thay đổi .find thành .findItem) và kết thúc bằng lỗi $ ('. List-box'). FindItem không phải là hàm – Rob

+0

Xin lỗi, tôi quên thêm rằng bạn đã có để ' return this; '... – James

2

Nếu bạn muốn các phương thức này có sẵn trên bất kỳ đối tượng jQuery nào, bạn sẽ phải thêm từng phương thức trong số đó vào mẫu thử của jQuery. Lý do là mỗi khi bạn gọi $(".list") một đối tượng mới được tạo và bất kỳ phương pháp nào bạn đã gắn với đối tượng trước đó sẽ bị mất.

Gán mỗi phương pháp để nguyên mẫu của jQuery như:

jQuery.fn.extend({ 
    list: function() { .. }, 
    findItem: function() { .. }, 
    sort: function() { .. } 
}); 

Các list phương pháp ở đây là đặc biệt vì nó có thể được gọi hai lần. Đầu tiên, khi khởi tạo danh sách và thứ hai khi tìm các mục cụ thể theo điều kiện. Bạn sẽ phải phân biệt giữa hai trường hợp này bằng cách nào đó - hoặc bằng kiểu đối số hoặc một số tham số khác.

Bạn cũng có thể sử dụng API data để ném ngoại lệ nếu các phương pháp này được gọi cho một đối tượng chưa được khởi tạo bằng plugin danh sách.Khi ('xyz').list({ .. }) được gọi đầu tiên, lưu trữ một số biến trạng thái trong bộ nhớ cache dữ liệu cho đối tượng đó. Khi bất kỳ phương thức nào khác - "list", "findItem" hoặc "sort" được gọi sau đó, hãy kiểm tra xem đối tượng có chứa biến trạng thái đó trong bộ đệm dữ liệu của nó không.

Cách tiếp cận tốt hơn là đặt tên miền cho plugin của bạn để list() sẽ trả về đối tượng mở rộng. Ba phương thức mở rộng có thể được gọi trên giá trị trả về của nó. Giao diện sẽ như sau:

$('selector').list({ ... }); 
$('selector').list().findOne(..); 
$('selector').list().findAll(..); 
$('selector').list().sort(); 

Hoặc lưu tham chiếu đến đối tượng được trả lại lần đầu tiên và gọi phương thức trực tiếp trên đối tượng đó.

var myList = $('selector').list({ ... }); 
myList.findOne(..); 
myList.findAll(..); 
myList.sort(); 
+0

Cảm ơn thông tin, điều đó thực sự rất hữu ích cuối cùng tôi cũng nhận ra tại sao phương pháp của tôi không tồn tại. Tôi không thể làm danh sách '$ list = $ ('. List'). (Danh sách {)};' và sử dụng $ list từ điểm đó? Dù sao, tôi tìm thấy một giải pháp khác, tôi sẽ đăng nó như một câu trả lời. 1 mặc dù cảm ơn – Rob

+0

@Rob - Bạn có thể làm điều đó, miễn là bên trong phương thức 'list', bạn mở rộng đối tượng jQuery với tất cả các hàm bạn cần, và từ điểm này trở đi tham chiếu' $ list' để gọi những hàm đó. Điều đó nói rằng, tôi nghĩ rằng cách tiếp cận của bạn là tốt hơn. – Anurag

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