2011-12-19 32 views
11

Tôi muốn một người nghe sự kiện duy nhất kích hoạt bất cứ khi nào trường bất kỳ nào có dạng (ví dụ: Ext.form.Panel) thay đổi. Tuy nhiên, lớp Ext.form.Panel không kích hoạt một sự kiện cho chính nó.ExtJS 4: Làm thế nào để biết khi nào bất kỳ trường nào trong biểu mẫu (Ext.form.Panel) thay đổi?

Cách tốt nhất để nghe sự kiện 'thay đổi' cho tất cả các trường trong biểu mẫu là gì?

Trả lời

18

Cập nhật: (! Nhờ @innerJL) Thêm một lựa chọn thứ 3 dựa trên mũi trong ý kiến ​​

Ok, có vẻ như có ít nhất hai cách khá đơn giản để làm điều đó.

Lựa chọn 1) Thêm một 'thay đổi' người nghe với từng lĩnh vực được thêm vào biểu mẫu:

Ext.define('myapp.MyFormPanel', { 
    extend: 'Ext.form.Panel', 
    alias: 'myapp.MyFormPanel', 
    ... 

    handleFieldChanged: function() { 
    // Do something 
    }, 

    listeners: { 
    add: function(me, component, index) { 
     if(component.isFormField) { 
     component.on('change', me.handleFieldChanged, me); 
     } 
    } 
    } 
}); 

này có ít nhất một nhược điểm lớn; nếu bạn "bọc" một số trường trong các vùng chứa khác và sau đó thêm các vùng chứa đó vào biểu mẫu, nó sẽ không nhận ra các trường lồng nhau. Nói cách khác, nó không thực hiện tìm kiếm "sâu" thông qua thành phần để xem nó có chứa trường biểu mẫu cần trình lắng nghe 'thay đổi' hay không.

Tùy chọn 2) Sử dụng truy vấn thành phần để nghe tất cả các sự kiện 'thay đổi' được kích hoạt từ các trường trong vùng chứa.

Ext.define('myapp.MyController', { 
    extend: 'Ext.app.Controller', 
    ... 

    init: function(application) { 
    me.control({ 

     '[xtype="myapp.MyFormPanel"] field': { 
      change: function() { 
       // Do something 
      } 
     } 
    }); 
    } 
}); 

Lựa chọn 3) Nghe cho 'dirtychange' sa thải khỏi cơ bản hình thức 'cơ bản' dưới dạng bảng của (Ext.form.Basic). Quan trọng: Bạn cần đảm bảo bạn phải bật 'trackResetOnLoad' bằng cách đảm bảo rằng {trackResetOnLoad: true} được truyền cho hàm tạo bảng biểu mẫu của bạn.

Ext.define('myapp.MyFormPanel', { 
    extend: 'Ext.form.Panel', 
    alias: 'myapp.MyFormPanel', 
    constructor: function(config) { 
    config = config || {}; 
    config.trackResetOnLoad = true; 
    me.callParent([config]); 

    me.getForm().on('dirtychange', function(form, isDirty) { 
     if(isDirty) { 
      // Unsaved changes exist 
     } 
     else { 
      // NO unsaved changes exist 
     } 
    }); 
    } 
}); 

Cách tiếp cận này là "thông minh nhất"; nó cho phép bạn biết khi nào biểu mẫu đã được sửa đổi, nhưng cũng nếu người dùng sửa đổi nó trở lại trạng thái ban đầu của nó. Ví dụ: nếu họ thay đổi trường văn bản từ "Foo" thành "Bar", sự kiện 'dirtychange' sẽ kích hoạt 'true' cho tham số isDirty. Nhưng nếu người dùng sau đó thay đổi trường trở lại thành "Foo", sự kiện 'dirtychange' sẽ kích hoạt lần nữa và isDirty sẽ là false.

+1

có lẽ sự kiện này của BasicForm (yourForm.getForm()) có thể có ích cho bạn http://docs.sencha.com/ext-js/4-0/ #!/api/Ext.form.Basic-event-dirtychange –

+0

Nếu có ai có giải pháp cho ExtJs 3, tôi sẽ quan tâm. – gunnx

+1

Hãy cẩn thận với tùy chọn thứ 3. Trình nghe sẽ chỉ được kích hoạt khi thuộc tính 'isDirty' của biểu mẫu thay đổi. Điều đó có nghĩa là nếu bạn có trường văn bản có giá trị "Foo" và các thay đổi của người dùng có giá trị thành "Bar" - 'dirtychange' sẽ được kích hoạt. Nhưng nếu giá trị thay đổi của người dùng lại thành "Pool" 'dirtychange' sẽ KHÔNG được kích hoạt vì thuộc tính' isDirty' đã là 'true' –

6

Tôi muốn bổ sung cho câu trả lời của Clint. Có một cách tiếp cận khác (và tôi nghĩ đó là cách tốt nhất cho vấn đề của bạn). Chỉ cần thêm change nghe để hình thành giá trị mặc định của cấu hình:

Ext.create('Ext.form.Panel', { 
    // ... 
    defaults: { 
     listeners: { 
      change: function(field, newVal, oldVal) { 
       //alert(newVal); 
      } 
     } 
    }, 
    // ... 
}); 
+0

Cảm ơn bạn đã nhập! Trong trường hợp của tôi, tôi thực sự cần một lớp tùy chỉnh mở rộng bảng điều khiển biểu mẫu; Tôi cũng chỉ muốn biết khi nào một trường được thay đổi từ giá trị ban đầu của nó ('dirtychange' so với'thay đổi') nhưng đây có thể là lời khuyên tuyệt vời cho các tình huống khác khi hai yêu cầu đó không áp dụng. –

+0

Không có sự kiện thay đổi nào trong bảng điều khiển biểu mẫu, cũng như không nghe nó. – Marshal

+2

@Marshal. Tôi không viết mẫu đó có sự kiện như vậy. Các trường biểu mẫu có các sự kiện như vậy. Trong trình xử lý ví dụ của tôi KHÔNG được gán cho biểu mẫu. Nó được gán cho tất cả các trường của biểu mẫu. Xem cấu hình [mặc định] (http://docs.sencha.com/extjs/4.2.0/#!/api/Ext.form.Panel-cfg-defaults). –

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