2011-09-20 45 views
8

Tôi có câu hỏi liên quan đến xử lý sự kiện trên phía máy khách trong GWT.Thực tiễn tốt nhất Xử lý sự kiện GWT

Trong ứng dụng của chúng tôi, chúng tôi có một cấu trúc khá phức tạp của các mô-đun khác nhau và các trang được giao tiếp thông qua các eventbus gwt trên phía khách hàng. Bây giờ số lượng các sự kiện đang phát triển nhanh cho ý kiến ​​của tôi. Ví dụ. Tôi mở một popup tôi cần:

  1. Một sự kiện cho việc mở cửa sổ bật lên
  2. Một sự kiện đã hỏi một số dữ liệu trong phạm vi khách hàng
  3. Một sự kiện để nhận lại dữ liệu và điền vào hộp thoại
  4. một sự kiện đóng popup
  5. một sự kiện để xử lý các lưu nút

tôi nghĩ một chút đến phức tạp hoặc thiếu cái gì đó trong EventBus thực hiện? Tôi chỉ muốn có một số phản hồi từ cộng đồng khi bạn đang đối mặt với cùng một vấn đề.

Trả lời

10

Đối với những gì đáng giá, tôi có rất nhiều sự kiện và phát triển hơn. Và có, tôi tự hỏi nếu tôi có thể làm với ít hơn, nhưng khi tôi bỏ qua một sự kiện và các yếu tố liên kết trực tiếp, tôi rất tiếc nó.

Đây là ví dụ mà tôi vừa sửa vào hôm qua. Tôi có một widget DataGrid. Tôi cũng hỗ trợ sắp xếp lại các cột, ẩn cột, định lại kích thước cột và tô màu cột bằng hộp thoại bật lên. Bạn nhấp vào nút cấu hình và cửa sổ bật lên với các cột được liệt kê cho thấy và người dùng có thể nhấp vào hộp kiểm để hiển thị hoặc ẩn cột, nhấp vào nút Di chuyển lên/Di chuyển xuống để sắp xếp lại các cột, v.v. Nhấn Áp dụng trên cửa sổ bật lên và cửa sổ bật lên biến mất và cấu hình lại DataGrid.

Trừ trường hợp không. Bạn click vào Apply và popup sẽ chỉ ngồi đó, người dùng sẽ tự hỏi điều gì đang xảy ra, DataGrid sẽ cấu hình lại bên dưới, và sau đó popup sẽ biến mất. Chúng tôi chỉ nói một khoảng thời gian ngắn - có thể là một giây hoặc hơn một chút - nhưng nó quá đáng chú ý. Tại sao nó lại xảy ra? Bởi vì tôi đã lười biếng và gắn cửa sổ bật lên trực tiếp vào nút cấu hình và nút Áp dụng trực tiếp vào DataGrid. Ví dụ, bạn sẽ nhấn Apply và cuộc gọi sẽ được thực hiện cho DataGrid với thông tin cấu hình mới. Chỉ khi cuộc gọi được trả lại thì cửa sổ bật lên sẽ bị rách.

Tôi biết điều đó thật tệ khi tôi làm điều đó, nhưng tôi đã lười biếng. Vì vậy, tôi đã dành 20 phút tôi cần viết hai thông điệp và các trình xử lý liên quan trong singleton hòa giải của tôi. Một thông báo được DataGrid phát hành để bắt đầu hộp thoại cấu hình và một thông báo được bật bởi cửa sổ bật lên để định cấu hình DataGrid. Bây giờ các vật dụng được de-coupled, và hiệu suất là nhiều snappier. Không có cảm giác "dính".

Bây giờ đến ví dụ của bạn, bạn có thể không kết hợp (1) và (2) không? Và cũng có thể (3), (4), và (5)? Khi người dùng nhấp vào nút cấu hình trên ứng dụng của tôi, sự kiện sẽ mang theo thông tin cấu hình hiện tại (bao gồm tham chiếu đến DataGrid đã khởi tạo yêu cầu). Bạn có thể gọi thông tin này là "tải trọng". Khi người dùng nhấp vào nút Áp dụng trên cửa sổ bật lên, trọng tải sự kiện bao gồm tất cả thông tin cấu hình mới (bao gồm tham chiếu đến mục tiêu ban đầu đó là DataGrid) mà trình xử lý sự kiện cấp cho đối tượng DataGrid khi sự kiện được xử lý. Hai sự kiện - một sự kiện để khởi động cấu hình và một để áp dụng kết quả cuối cùng.

Có rất nhiều sự kiện trong bất kỳ ứng dụng nào thú vị nhưng sự kiện có thể mang nhiều thông tin, vì vậy tôi sẽ xem liệu tổ chức sự kiện của bạn có bị gãy hay không.


Thêm một chút, đây là mã tôi sử dụng. Tôi không biết sao chép các yếu tố của mẫu này từ một trong các ví dụ của Google.

Người dùng có thể yêu cầu giúp đỡ bằng cách sử dụng mục trình đơn:

@UiField 
MenuItem help; 

help.setCommand(new Command() { 
     @Override 
     public void execute() { 
     BagOfState.getInstance().getCommonEventBus().fireEvent(new MenuHelpEvent()); 
     } 
    }); 

Đối với sự kiện này (trong trường hợp này, sự kiện này phát sinh khi người dùng nhấp vào Trợ giúp mục trình đơn):

public class MenuHelpEvent extends GwtEvent<MenuHelpEvent.Handler> { 

    private static final Type<Handler> TYPE = new Type<Handler>(); 

    public interface Handler extends EventHandler { 
    void doMenuHelp(); 
    } 

    @Override 
    public GwtEvent.Type<Handler> getAssociatedType() { 
    return TYPE; 
    } 

    @Override 
    protected void dispatch(Handler handler) { 
    handler.doMenuHelp(); 
    } 

    public static HandlerRegistration register(EventBus eventBus, Handler handler) { 
    return eventBus.addHandler(TYPE, handler); 
    } 

} 

Tôi có một singleton được gọi là Người hòa giải, trong đó TẤT CẢ các sự kiện được đăng ký:

MenuHelpEvent.register(BagOfState.getInstance().getCommonEventBus(), 
    new MenuHelpEvent.Handler() { 
     @Override 
     public void doMenuHelp() { 
     new MenuHelp().execute(); 
     } 
    }); 

Mọi sự kiện được giao phối với C đối tượng ommand để thực hiện công việc:

public class MenuHelp implements Command { 

     @Override 
     public void execute() { 
     new InfoMessage(BagOfState.APP_MSG.unimplementedFeatureCaption()) 
      .setTextAndCenter(BagOfState.APP_MSG.unimplementedFeature()); 
     } 

    } 

Mọi thứ đều được tách riêng. Tiện ích menu được gắn với lệnh thực thi và sau đó hoàn tất. Lệnh này kích hoạt sự kiện trên bus sau đó hoàn tất. Sự kiện này sẽ kích hoạt việc thực hiện một Lệnh và hoàn thành. Lệnh này hiển thị bảng trợ giúp bật lên (trong trường hợp này, một thông báo "chưa được thực hiện" cho người dùng - vâng, tôi sẽ đến sớm). Mọi tương tác với đầu vào của người dùng được xử lý cực kỳ nhanh chóng và giải quyết. Nó có thể khởi động một loạt các sự kiện để thực hiện một hành động dài, nhưng không bao giờ buộc lên GUI để làm như vậy. Và tất nhiên, vì các phần tử được tách rời, tôi có thể gọi các phần tử giống nhau ở những nơi khác (ví dụ, gọi lệnh trợ giúp thông qua một nút nhấn cũng như một mục menu).

+0

Đó là lời khuyên tuyệt vời, tôi sẽ thử và dính vào đó. –

+0

Tôi đang tìm cách giải quyết vấn đề này với một số giải pháp hoạt động như 'xử lý sự kiện', ở đây chúng tôi có một ví dụ tuyệt vời. Cảm ơn bạn. – user1445967

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