【问题标题】:Access variable from inner onClick method in outer class in Wicket从 Wicket 外部类中的内部 onClick 方法访问变量
【发布时间】:2021-01-15 16:06:28
【问题描述】:

我有一个看起来像这样的课程

    private static class LinkTest extends WebMarkupContainer {
        public LinkTest(String id) {
            super(id);
            AjaxLink<Object> link = new AjaxLink<>("link") {
                @Override
                public void onClick(AjaxRequestTarget target) {
                    String content = //... some function call
                }
            };
            add(link);
            // .. how to access "content" variable here
            link.add(new Label("label", Model.of(content)));
            add(new AttributeAppender("onclick",
              new Model(format("alert('%s');", contentModel)), ";"));
        }
    }

我想访问 LinkTest 构造函数中的“内容”变量。有什么想法吗?

【问题讨论】:

    标签: java wicket


    【解决方案1】:
    private static class LinkTest extends WebMarkupContainer {
      public LinkTest(String id) {
        super(id);
    
        // 1
        IModel<String> contentModel = Model.of("initial value");
        AjaxLink<String> link = new AjaxLink<>("link", contentModel) {
            @Override
            public void onClick(AjaxRequestTarget target) {
                // 2
                contentModel.setObject("a new value");
    
                // 3
                target.add(this.get("label"));
    
                // 5
                target.appendJavaScript("alert('"+contentModel.getObject()+"');");
            }
        };
        add(link);
        Label label = new Label("label", contentModel);
        link.add(label);
        //4
        label.setOutputMarkupId(true);
    }
    

    }

    1. 这个想法是为content 使用一个可共享的容器。在 Wicket 中,这是模型 (IModel)。
    2. 点击链接后更新模型
    3. 要更新标签,您需要将其添加到 AjaxRequestTarget。
    4. 不要忘记通过调用 .setOutputMarkupId(true) 来更新 Label Ajax
    5. 通过使用target.appendJavaScript(CharSequence),您可以将新计算的content发送到浏览器

    【讨论】:

    • 谢谢,但我还需要进行 JS 调用,并且 contentModel 始终作为初始值,而不是我在 onClick 事件中分配的新值 add(new AttributeAppender("onclick", new Model(format("alert('%s');", contentModel)), ";"));
    • 我已将 // 5 添加到我的答案中。通过使用 AttributeAppender,您可以将属性值设置为 contentModel 的初始值。您需要使用target.appendJavaScript(...)点击链接后发送更新的值。
    • 如果我在警报contentModel.getObject() 中设置为参数,什么都不会发生,但如果我使用alert('Test') 作为示例,那么我会在单击时看到弹出消息。任何想法为什么 javascript 不能与 contentModel 一起使用?
    • 我猜由于生成的字符串中未转义(单|双)引号导致 JavaScript 错误。检查浏览器的开发工具控制台。
    • 好的,是因为“\0\n”这样的字符,对吧?我在开发工具控制台中看到错误 VM72:1 Uncaught SyntaxError: Invalid or unexpected token at Object.addElement (core-v-3837323131636430.js:formatted:5174)....
    【解决方案2】:

    通过在两个组件之间共享模型来轻松解决。

    private static class LinkTest extends WebMarkupContainer {
        public LinkTest(String id) {
            super(id);
            IModel<String> contentModel = ()-> /* some function call */;
            AjaxLink<String> link = new AjaxLink<>("link", contentModel) {
                @Override
                public void onClick(AjaxRequestTarget target) {
                    target.add(this);
                    target.appendJavaScript("alert('"+getModelObject()+"');");
                }
            };
            add(link);
            // .. how to access "content" variable here
            link.add(new Label("label", contentModel));
        }
    }
    

    【讨论】:

    • 真的不行,模型没有最新的值。我在我的帖子中添加了一行代码,我称之为 javascript 行为并且 contentModel 为空
    • 也许模型正在更新,但您看不到值,因为label 从未更新?对于 ajax 调用,您始终必须指定具有 setOutputMarkupId(true) 的组件。在这种情况下,您可以在setModelObject(content) 之后写target.add(this)
    • 右标签永远不会更新,所以在 AjaxLink 类之外 contentModel 总是空的。每次单击链接时,我都需要重新渲染标签并获取 contentModel 的实际值。我应该使用LoadableDetachableModel 吗?
    • 我更新了使用 java 8s lambdas 进行函数调用的示例。是否要使用可加载的可拆卸模型取决于您获取的数据以及调用的成本。
    • 你的意思是target.add(this) 吗?现在页面每次点击事件后都会重新加载,并且没有弹出警告消息
    【解决方案3】:

    匿名类可以访问其封闭类的成员。所以你可能会做这样的事情

    private static class LinkTest extends WebMarkupContainer {
         //Here!
         String content;
         
         public LinkTest(String id) {
            super(id);
            AjaxLink<Object> link = new AjaxLink<>("link") {
                @Override
                public void onClick(AjaxRequestTarget target) {
                    content = //... some function call
                }
            };
            add(link);
            // .. how to access "content" variable here
            link.add(new Label("label", Model.of(content)));
        }
    }
    

    【讨论】:

    • 我不认为帽子会起作用。标签将始终显示为空。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多