【问题标题】:Method called twice GWT方法调用了两次 GWT
【发布时间】:2011-02-19 19:17:29
【问题描述】:

我正在使用 GWT 创建一个 Web 应用程序。我有一个方法 bookMode(),它使用一些文本框、列表框等构建 UI,并将其显示在对话框中。我这样调用方法:

//listen for mouse events on the add button
    addButton.addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {

            String check = Cookies.getCookie("role");
            if(check == "TopBeheerder") {   
                boolean currentMode = mode0.getValue();
                add addObject = new add();
                if(currentMode == true) {
                    addObject.bookMode();
                }
                if(currentMode == false) {
                    addObject.userMode();
                }   
            }
            else {
                BibPhp.notification("You don't have enough permissions.");
            }


        }
    });

当我使用 GWT.log() 函数时,我注意到这个方法被调用了两次。但是我使用 eclipse 搜索功能搜索了我的所有代码,并且该方法没有被调用两次。我不知道为什么 GWT 会这样。方法 userMode() 也被调用了两次。

【问题讨论】:

  • 澄清一下,您遇到的行为是每次“onclick”事件都会执行两次点击处理程序代码?
  • 是的,当我点击 addButton 时,它会执行两次该方法
  • 好吧,看来没有什么问题。我只是确保事件处理程序不会被无意添加两次,即确保没有以某种方式对 addClickHandler() 进行两次调用。在调用 addClickHandler() 确认之前放置一个 Window.alert()。
  • 好的,我在 onClick 方法中添加了一个 Window.alert(),我收到了两次警报,我只单击了一次。我不知道为什么会这样。我在其他按钮上也有同样的问题,但不是全部。还有一些按钮,我必须点击两次才能调用事件。
  • 把 alert 放在 addButton.addClickHandler(...) 下面看看是一次还是调用了两次。

标签: java javascript gwt methods


【解决方案1】:

当 Java 代码转换为 HTML 和 Javascript 时; java和javascript之间的相等比较是不一样的。因此,如果您在 HTML 中有两个具有相同 id 的小部件(按钮),并为每个小部件添加点击处理程序,那么同一个小部件很可能会添加两次点击处理程序。尝试为按钮小部件设置不同的 ID,这有助于我解决与多次点击处理程序调用相关的任何问题。

【讨论】:

    【解决方案2】:

    我的猜测是,不知何故,您添加了两次 ClickHandler。

    我会做这样的事情来调试:

    System.out.println("adding click handler!");
    addButton.addClickHandler(new ClickHandler() { ...
    

    如果您看到“添加点击处理程序!”打印两次,这就是你的答案。

    不久前我在实现 MVP 模式时遇到了类似的问题。 View 是静态的并且只初始化一次,然而,Presenter 每次请求 Place 时都会被初始化。每次Presenter初始化时都会绑定click事件,依次添加ClickHandler多次。

    【讨论】:

      【解决方案3】:

      我在使用 GWT 按钮时遇到了类似的问题。

      我在名为“Widgets.java”的类中创建了一个按钮,而没有在该类中编写侦听器。然后我将此按钮用作“ClassName.ButtonName”,就像一个宏:“Widgets.myButton”。

      当然,在某个时刻,我从另一个类中为这个引用的按钮添加了一个侦听器,虽然我正在删除和清理完整的 RootPanel,但当我不得不再次重绘具有相同名称的按钮时,它似乎按钮 KEPT 监听器已经关联并再次添加了一个新的。

      所以每次我单击该按钮时,与之关联的函数都会运行两次。

      解决方案?只需停止使用对 Button 的“引用”并在本地创建它。

      我读了这个帖子,它“启发”了我找到我的解决方案,只是想赚我的两分钱。 :)

      【讨论】:

        【解决方案4】:

        我是这样解决的: 我声明了一个像这样的处理程序注册变量

        private HandlerRegistration HandlerButton;
        

        那么当你需要调用addbutton方法时,使用之前创建的变量

        HandlerButton=addButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
        
                String check = Cookies.getCookie("role");
                if(check == "TopBeheerder") {   
                    boolean currentMode = mode0.getValue();
                    add addObject = new add();
                    if(currentMode == true) {
                        addObject.bookMode();
                    }
                    if(currentMode == false) {
                        addObject.userMode();
                    }   
                }
                else {
                    BibPhp.notification("You don't have enough permissions.");
                }
        
              event.stopPropagation();
              event.preventDefault();     
              HandlerButton.removeHandler();
            }
        });
        

        在方法结束时,您只需调用 stopPropagation(),preventDefault() 并删除处理程序以确保它不会触发超过一次

        【讨论】:

        • 你应该用小写命名你的变量:handlerButton。这是 java 约定。
        【解决方案5】:

        有两种方法可以解决这个问题:

        1) 放在触发两次这两种方法的对象之后

        Event.stopPropagation();
        Event.preventDefault();
        

        如果您使用的是键/鼠标等处理程序,则只需将 Event 替换为 arg0。 如果这不能停止调用它两次,请使用第二种方式

        2) 在类中声明这个变量 -> private RegistrationHandler stopHandler;

        然后当您添加点击/鼠标/按键处理程序时,请写下:

            stopHandler=addButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
        
                String check = Cookies.getCookie("role");
                if(check == "TopBeheerder") {   
                    boolean currentMode = mode0.getValue();
                    add addObject = new add();
                    if(currentMode == true) {
                        addObject.bookMode();
                    }
                    if(currentMode == false) {
                        addObject.userMode();
                    }   
                }
                else {
                    BibPhp.notification("You don't have enough permissions.");
                }
        
              stopHandler.removeHandler();<-----------------
            }
        });
        

        stopHandler.removeHandler() 放在哪里需要停止重复两次。

        p.s:如果找不到removeHandler()方法,就写stopHandler(.dot)再搜索方法

        【讨论】:

          猜你喜欢
          • 2017-10-15
          • 2011-02-09
          • 1970-01-01
          • 2023-03-28
          • 2011-09-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-22
          相关资源
          最近更新 更多