2012-03-02 34 views
9

Tôi xây dựng ứng dụng ExtJS 4 của tôi theo cấu trúc MVC. Tôi muốn tạo một MyGrid lưới mở rộng với một số chức năng mà tôi có thể sử dụng lại nhiều lần. Vì vậy, tôi đoán, nó cần phải có bộ điều khiển riêng của nó mà cũng được mở rộng, để các chức năng được thừa hưởng. Làm thế nào là điều này đúng cách?Mở rộng bộ điều khiển trong ứng dụng ExtJS 4 MVC

Trong mã bên dưới, tôi minh họa cách tôi mở rộng bộ điều khiển MyGrid bằng MyExtendedGrid. Tôi nhận ra rằng tôi đang ghi đè hàm init trong bộ điều khiển MyGrid, để nó không bao giờ được gọi. Vấn đề có được giải quyết đơn giản bằng cách gọi "super" init trong MyGrid từ MyExtendedGrid init hoặc hợp nhất các đối tượng kiểm soát? Đó có phải là cách thích hợp để làm điều này trong tinh thần MVC không? Nếu vậy, làm thế nào?

điều khiển/MyGrid.js:

Ext.define('App.controller.MyGrid', { 
    extend: 'Ext.app.Controller', 
    refs: [ 
     { 
      ref: 'myGridView', 
      selector: 'mygrid' 
     } 
    ], 
    init: function() { 
     var me=this; 
     me.control({ 
      'mygrid textfield[name=searchField]': { 
       change: function() { 
        var view = me.getMyGridView(); 
        // Do something with view 
       } 
      } 
     }); 
    } 
}); 

điều khiển/MyExtendedGrid.js:

Ext.define('App.controller.MyExtendedGrid', { 
    extend: 'App.controller.MyGrid', 
    views: [ 
     'grids.MyExtendedGrid'], 
    refs: [ 
     { 
      ref: 'myExtendedGridView', 
      selector: 'myextendedgrid' 
     } 
    ], 
    init: function() { 
     var me=this; 
     me.control({ 
      'myextendedgrid': { 
       // Some control code 
       // Using getMyExtendedGridView() 
      } 
     }); 
    } 
}); 

xem/lưới/MyGrid.js:

Ext.define('App.view.grids.MyGrid', { 
    extend: 'Ext.grid.Panel', 
    alias : 'widget.mygrid', 
    requires: [ 
    ], 
    store: '', // Not defined here 
    columns: [ ], // Not defined here 

    initComponent: function() { 
     var me = this; 
     me.tbar = [ 
      'Search', 
      { 
       xtype: 'textfield', 
       name: 'searchField', 
       hideLabel: true, 
       width: 150 
      } 
     ]; 
     me.callParent(arguments); 
    } 
}); 

xem/lưới/MyExtendedGrid .js:

Ext.define('App.view.grids.MyExtendedGrid', { 
    extend: 'App.view.grids.MyGrid', 
    alias : 'widget.myextendedgrid', 
    store: 'MyStore', 
    columns: [ 
     // ... 
    ], 

    initComponent: function() { 
     var me = this; 
     me.bbar = [ 
      //... 
     ]; 
     me.callParent(arguments); 
    } 
}); 

Trả lời

2

Ok, sau một số suy nghĩ tôi đã quyết định giải pháp sau, có lợi thế là mygrid không cần biết về myextendedgrid.

Tôi mở rộng GridView như trong câu hỏi.

Tôi đã cho lưới cơ sở bộ điều khiển riêng của mình để thực hiện chức năng phổ biến, ví dụ deleteButton.setDisable(false) khi có gì đó được chọn trong lưới.

Tiếp theo, tôi tự nhắc mình rằng sử dụng refs:[ (ví dụ: selector: 'mygrid') sẽ chỉ rõ ràng cả hai trường hợp của lớp cơ sở bất kỳ phiên bản mở rộng nào.Khi sử dụng me.control({ tôi thay vì nhận được lưới có liên quan bằng cách đi qua từ các yếu tố kích hoạt sử dụng up:

me.control({ 
    'mygrid textfield[name=searchField]': { 
     change: function(searchfield) { 
      var grid=searchfield.up('mygrid'); // (mygrid or myextendedgrid!) 
      // Do something with view 
     } 
    } 
... 

Lưới mở rộng tôi cung cấp cho bộ điều khiển riêng của mình và ở đây tôi có thể sử dụng refs. Tôi không mở rộng bộ điều khiển từ lớp MyGrid (nhưng thay vì từ 'Ext.app.Controller'), trừ khi tôi muốn sử dụng các hàm hoặc biến từ bộ điều khiển MyGrid. Tất cả các bộ điều khiển được bắt đầu từ app.js sử dụng:

Ext.application({ 
    controllers: [ 
     'MyGrid' 
     'MyExtendedGrid', 
    ], 
... 

Để có được lưới khi hàng được lựa chọn trong lưới, tôi lưu trữ lưới trong mô hình lựa chọn như sau:

Trong điều khiển/MyGrid.js:

me.control({ 
    'mygrid': { 
     afterrender: function(grid) { 
      var selModel=grid.getSelectionModel(); 
      selModel.myGrid=grid; 
     }, 
     selectionchange: function(selModel, selected, eOpts) { 
      var grid=selModel.theLookupGrid; 
      // Do something with view 
     } 
... 
1

Nó thực sự là một chút phức tạp hơn ...

Đây là những gì chúng tôi đã làm trong ứng dụng của chúng tôi (chúng tôi có chính xác cùng một tình huống - một số loại điều khiển cơ sở, đó là tái sử dụng ở nhiều nơi khác nhau)

  1. Giữ chức năng init trong bộ điều khiển cơ sở.

  2. Xác định phương thức cơ sở chung trong bộ điều khiển cơ sở này (như gridRendered - nơi bạn cần phải làm điều gì đó cho tất cả bộ điều khiển mọi lúc).

  3. Đăng ký các sự kiện trong tất cả các trình điều khiển con nhưng đăng ký sự kiện bằng các phương pháp của bộ điều khiển cơ sở. Nó sẽ không hoạt động nếu không - bộ điều khiển cơ sở không có refs đúng để đăng ký đúng các sự kiện.

Tôi có thể đăng vài đoạn mã nguồn nhưng tôi nghĩ nó khá đơn giản.

+0

Cảm ơn, bạn đã cho tôi một số cảm hứng .. – Louis

+0

@sha Tôi thực sự sẽ thích nó nếu bạn đăng một hoặc hai đoạn mã. –

+0

@LeviHackwith: không sao cả. chúng ta hãy làm điều này trong câu hỏi riêng biệt để chúng ta không nhầm lẫn điều này. muốn đăng câu hỏi mới? – sha

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