2010-10-02 42 views
6

Tôi có một Dojo SubmitButton với jsId = "saveParamButtonWidget". Tôi overrided phương pháp onClick của nó bằng cách đặt:Ngăn chặn gửi biểu mẫu với Dojo

saveParamButtonWidget.onClick = editParam 

tôi xác định editParam() chức năng như thế này:

function editParam(eventObj) { 
    dojo.stopEvent(eventObj); 
    // ... 
} 

dojo.stopEvent() có nghĩa vụ phải dừng sự kiện bọt và xử lý mặc định. Tuy nhiên, trình duyệt sẽ vẫn gửi biểu mẫu. Tôi cũng đã thử với những điều sau:

function editParam(eventObj) { 
    eventObj.stopPropagation(); 
    eventObj.preventDefault(); 
    // ... 
} 

Điều tương tự. Cách duy nhất tôi đã quản lý để ngăn gửi biểu mẫu là bằng cách trả lại "sai" từ trình xử lý sự kiện:

function editParam(eventObj) { 
    // ... 
    return false; 
} 

Có thể ai đó cho tôi biết tại sao hai cách đầu tiên không hoạt động? Cảm ơn.

+0

Xin vui lòng cho hơn thông tin: bạn đã sử dụng loại widget nào (tên đầy đủ), dojo không biết "SubmitButton", tôi cho rằng đây là một tệp dijit.form.Button, với kiểu "submit". Đoạn mã sẽ giúp ích rất nhiều –

+0

Tôi xin lỗi, tôi đã sử dụng phần tử Gửi Dojo của Zend Framework, được gọi là SubmitButton. Nhưng bạn là đúng, nó là một dijit.form.Button với kiểu "submit". – Dario

Trả lời

23

Được rồi, sau khi thực hiện một số thông qua nguồn, tôi tin rằng tôi có thể trả lời câu hỏi của bạn một cách dứt khoát.

Lý do dojo.stopEvent() không hoạt động, nhưng return false, là hoàn toàn do cách mã dijit.form.Button được mã hóa. Nếu bạn quan tâm, đó là thời gian cho một chuyến đi thực địa nhỏ. Giữ mũ cứng của bạn trên.

Khi một dijit.form.Button được nhấp ...

  1. phương pháp của nút _onButtonClick được gọi. (Điều này được nối trong mẫu, với sự kiện ondijitclick đặc biệt không chỉ nắm bắt được nhấp chuột mà còn cả các lần bấm phím nhất định, cho mục đích an toàn.)
  2. Phương pháp _onButtonClick trước tiên gọi phương thức _onClick, trong đó, giả sử nút này không bị tắt (không phải trong trường hợp này), gọi và trả về kết quả của phương thức onClick. Đây là mối quan tâm đặc biệt vì đó là phương pháp bạn ghi đè!
  3. Coming back to _onButtonClick, nếu _onClick trở chính xácfalse (ví dụ nếu handler onClick của bạn trở false), _onButtonClickngay bails ra. Đây là lý do tại sao trả về sai khiến mã của bạn hoạt động như mong muốn. Nhưng điều gì sẽ xảy ra nếu nó không được bảo lãnh ở đó? Hãy làm theo các đường mòn hơn nữa ...
  4. Tiếp theo, _onButtonClick kiểm tra xem nút này không một hậu duệ của một hình thức HTML thực tế, nhưng một hậu duệ của một widget với một phương pháp _onSubmit (vịt đánh máy). Tôi giả định rằng trong trường hợp của bạn, số bên trong một số thực (số dijit.form.Form đếm), vì vậy, chúng tôi sẽ bỏ qua điều này. (Tôi theo ấn tượng rằng con đường mã này sẽ không thực sự gửi lên, trong khi bạn dường như không.)
  5. Một điều kiện cuối cùng được kiểm tra: nếu nút có valueNode được xác định (có), phương pháp click nút được gọi. Thật không may, điều này tạo ra một đối tượng sự kiện hoàn toàn mới trên một nút vô hình input type="submit" dưới biểu mẫu của bạn và do đó bất cứ điều gì bạn cố gắng báo cho sự kiện ban đầu được hiển thị không chính thức và biểu mẫu tiếp tục gửi! Đây là lý do tại sao dojo.stopEvent không hoạt động - mã này trong số dijit.form.Button trả tiền hoàn toàn không cần lưu ý.

Tôi đã nấu món này làm bằng chứng về khái niệm hơi hạn chế (hãy nhớ mở firebug/etc.để nhận nhật ký): http://jsfiddle.net/Bf5H8/

Có lẽ đây là thứ cần đăng nhập dưới dạng lỗi, nhưng tôi cho rằng ý tưởng ban đầu có thể là hỗ trợ cơ chế return false nổi tiếng là đủ. Tất cả điều này được nói, có thể là việc ghi đè lên biểu mẫu là phù hợp hơn với sở thích của bạn hơn là ghi đè onClick của nút anyway (như S.Jones gợi ý), nhưng ít nhất điều này sẽ giải quyết được bí ẩn.

+0

Cảm ơn rất nhiều vì nỗ lực của bạn, Ken. – Dario

+0

Tôi đã kiểm tra với Doug về điều này, đó là do thiết kế. Khi phân tích của bạn cho thấy, sẽ rất rắc rối khi hỗ trợ stopEvent() vì có hai đối tượng sự kiện. Một ví dụ khác về nơi bạn cần trả về false là từ phương thức onSubmit trong một biểu mẫu. Trong trường hợp đó, thậm chí không có một đối tượng sự kiện nào để gọi stopEvent() trên đó. –

2

Câu hỏi thú vị. +1

Tôi tin rằng bạn phải sử dụng dojo.connect để kết nối chức năng của mình với sự kiện DOM để có quyền truy cập vào các phương thức đó với đối tượng sự kiện.

Xem: The Event Object (DojoTollkit.org Reference Guide)

Các tổ chức sự kiện Object

Khi bạn kết nối một chức năng để một DOM kiện với dojo.connect, Dojo đi chức năng của bạn một đối tượng sự kiện bình thường. Điều này có nghĩa là, bất kể trình duyệt của khách hàng là gì, bạn có thể tin cậy vào tập hợp các thuộc tính tiêu chuẩn về sự kiện và tập hợp các phương pháp để thao tác sự kiện.

Giả định rằng chức năng của bạn đã được gọi bằng dojo.connect và mất một luận tên kiện, như:

dojo.connect(dojo.byId("node"), "onclick", function(event){ 
    // the var 'event' is available, and is the normalized object 
}); 

...

Dojo bình thường hóa các phương pháp sau đây với một sự kiện đối tượng:

  • event.preventDefault — ngăn chặn đêm trước hành vi mặc định nt của (ví dụ, một liên kết từ tải một trang mới)
  • event.stopPropagation — ngăn chặn một sự kiện từ kích hoạt sự kiện một nút cha của

Bên cạnh đó, dojo.stopEvent (sự kiện) sẽ ngăn chặn cả hai hành vi mặc định bất kỳ bất kỳ tuyên truyền nào (bong bóng) của sự kiện .


Điều đó nói rằng, đặt một chức năng như hình dưới đây theo hình thức để thực hiện một số logic trước khi gửi, là một khá sạch sẽ, dễ hiểu & cách tiếp cận duy trì.

<script type="dojo/method" event="onSubmit"> 
    if (!this.validate()) { // or whatever else you'd like to evaluate 
     // insert calls here... 
     return false; 
    } 
    return true; 
<script> 

Chúc mừng.

+0

Về mặt kỹ thuật, không có gì xấu xảy ra khi thiết lập phương thức onClick trực tiếp, vì nó chỉ là một nhánh trong 'dijit._Widget' có nghĩa là bị móc nối. Trong thực tế, sử dụng dojo.connect (hoặc có lẽ tốt hơn, yourwidget.connect) sẽ thực sự làm * tồi tệ hơn * bởi vì sau đó 'return false' sẽ không hoạt động. –

2

tôi đã cùng một vấn đề cho việc sử dụng dojo.stopEvent

Vấn đề này được giải quyết vấn đề hình thức trình như thế này - ở đây nó là một hình thức đơn giản sử dụng để kết nối thông qua võ đường:

this.formId = dojo.byId("formId"); 
dojo.connect(this.formId, 'onsubmit', function(evt) { 
    var val_main = validate_this_form(0); 
     if(val_main == false) 
      dojo.stopEvent(evt); 
}); 
+0

lưu ý dojo.connect không được dùng bởi dojo.aspect và dojo.on –

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