简体   繁体   English

Wicket + Javascript

[英]Wicket + Javascript

I'm wrapping up a Javascript widget in a Wicket component. 我在Wicket组件中包装了一个Javascript小部件。 I want to let the JS side talk to the component. 我想让JS方面与组件对话。 What I've got so far: 到目前为止我得到了什么:

Component in question goes like 有问题的组件就像

talker = new GridAjaxBehavior();
this.add(talker);    

in constructor 在构造函数中

and then, later on, puts something like 然后,稍后,提出类似的东西

"var MyGridTalker = new talker(" + this.talker.getCallbackUrl() + ");";

into the JS. 进入JS。

where GridAjaxBehavior extends AbstractDefaultAjaxBehavior . GridAjaxBehavior扩展了AbstractDefaultAjaxBehavior I want GridAjaxBehavior to spit back some XML when the JS calls it. 我希望GridAjaxBehavior在JS调用时吐出一些XML。

Am I doing this the right way? 我这样做是对的吗? What should GridAjaxBehaviour do to spit back the XML? GridAjaxBehaviour应该做什么来回吐XML?

Thanks 谢谢

Spit back some XML for what? 吐出一些XML用于什么? Presumably to update the model or the view, yes? 大概是为了更新模型或视图,是吗?

The strength of Wicket is that you don't have to worry about the rendered HTML. Wicket的优势在于您不必担心呈现的HTML。 In Model-View-Controller terms, you set up the Controller to correctly modify the Model, and Wicket takes care of the View. 在模型 - 视图 - 控制器术语中,您设置Controller以正确修改模型,Wicket负责视图。

The separation is not entirely clear: in fact you can show/hide view components, or change then, and that can be seen as altering the View. 分离并不完全清楚:事实上,您可以显示/隐藏视图组件,或者更改视图组件,这可以被视为改变视图。

But what you generally don't have to do is directly manage the browser or javascript. 但你通常不需要做的是直接管理浏览器或javascript。 Wicket takes care of that, if you take care of making your changes in the Java code. 如果你负责在Java代码中进行更改,Wicket会处理这个问题。

In Wicket, the Ajax will call a method on your AjaxBehavior with an AjaxRequestTarget target. 在Wicket中,Ajax将使用AjaxRequestTarget目标在AjaxBehavior上调用方法。

In that method (or in methods called from it), you do whatever you need to do, updating models or views, and then you add to the target any view component that that has changed. 在该方法中(或从其中调用的方法),您可以执行任何操作,更新模型或视图,然后向目标添加已更改的任何视图组件。 Wicket takes care of updating the browser. Wicket负责更新浏览器。


Here's an example. 这是一个例子。 It's taken from some code I did, but heavily altered just to make explication clearer. 它来自我做过的一些代码,但是为了使解释更加清晰而进行了大量修改 The idea is simple: "chained" dropdown choices, where the options in the child change when the select option in the parent changes, as in the series of [State] [County] [District]. 这个想法很简单:“链式”下拉选项,当父级中的选项更改时,子项中的选项会发生变化,如[State] [County] [District]系列中所示。

(In the actual class, the Model change is passed to the child, which decides for itself if it has changed, and adds itself to the target if it has, then passes the target to its child. I've removed most of that to make a clearer example.) (在实际的类中,模型更改将传递给子级,子级会自行决定是否已更改,如果已更改,则将其自身添加到目标,然后将目标传递给其子级。我已将其中大部分更改为做一个更清楚的例子。)

Here's the ctor, which just adds to itself an anonymous subclass of an AjaxBehavior: 这是ctor,它只是添加了一个AjaxBehavior的匿名子类:

public AjaxChildNotifyingDropDownChoice(...code elided for clarity...) {
    this.child = child;

    // Ajax won't work without this:
    setOutputMarkupId(true);
    // 
    add( new OnChangeAjaxBehavior() {
        @Override
        public void onUpdate(final AjaxRequestTarget target) {

            // tell child to update its list
            // based on newly selected value

            // when the Ajax is called, 
            // my owning component's model
            // is already updated

            // note we could just type getModel()
            // I'm making explicit that we're calling it
            // on the enclosing class 
            // (which a non-static inner class has a hidden ref to) 
            child.setNewModelBasedOnSelectionOf( 
               AjaxChildNotifyingDropDownChoice.this.getModel());

            // now add the child to the target
            // Wicket javascript will receive the new 
            // options and re-render the child dropdown
            target.add(child);

        }
    });
}

We could also have hidden or un-hidden components, or added behaviors like CSS styles, or even swapped one Panel for another. 我们也可能有隐藏或未隐藏的组件,或添加CSS样式等行为,甚至将一个Panel换成另一个。 As long as for each changed component we: 1) called setOutputMarkupId(true); 只要每个更改的组件我们:1)调用setOutputMarkupId(true); so that the javascript can find it, and 2) added it to the AjaxRequestTarget 这样javascript就可以找到它,并且2)将它添加到AjaxRequestTarget中

Note that different types (subclases) of Ajax Behavior have different callback functions, so be sure you're overriding the right one (add an @Override annotation so the compiler can complain if you got the name wrong). 请注意,Ajax Behavior的不同类型(子类)具有不同的回调函数,因此请确保覆盖正确的回调函数(添加@Override注释,以便编译器可以在您输入错误名称时进行投诉)。

But again, the basic wicket idea is that instead of sending raw data for the client to parse and act on, you update your model and view, and tell Wicket to re-render what you've changed, by adding the chnaged components to the target. 但同样,基本的wicket想法是,不是发送客户端的原始数据进行解析和操作,而是更新模型和视图,并告诉Wicket重新呈现您已更改的内容,方法是将chnaged组件添加到目标。

The only reason I can think of to send straight XML would to be to feed it to non-Wicket javascript. 我可以想到发送直接XML的唯一原因是将它提供给非Wicket javascript。 Let me know if that's your aim, and I completely missed the point. 如果这是你的目标,请告诉我,我完全忽视了这一点。 ;) ;)

I don't really know what Wicket is or what it does, but there is a minor bug in your code (as it appears). 我真的不知道Wicket是什么或它做了什么,但是你的代码中有一个小错误(如图所示)。

This: 这个:

"var MyGridTalker = new talker(" + this.talker.getCallbackUrl();

You seem to be missing your end parens: 你似乎错过了你的最终结局:

"var MyGridTalker = new talker(" + this.talker.getCallbackUrl() + ")";

Anyway, not a big deal, but didn't know if it was intentional. 无论如何,没什么大不了的,但不知道是不是故意的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM