2 Replies Latest reply on Apr 8, 2009 5:55 PM by wuguangyi

    Injecting context variable to child component

    wuguangyi

      I am a new Seam user and is struggling with this simple question. Please bear with me. What is the best approach for a parent component to invoke child component with different context variable injected? The test code is posted blow to illustrate:



      @Name("parent")
      @Scope(ScopeType.SESSION)
      public class ParentAction {
      
          @In private ChildAction child;
      
          @In private List<Booking> bookingList;
      
          public void confirm() {
              for (Booking booking : bookingList) {
                  ScopeType.EVENT.getContext().set("booking", booking);
                  child.confirm();
              }
          }
      }



      To make it work, I set the context directly through ScopeType.EVENT.getContext().set("booking", booking) but I don't feel comfortable with this approach. Another approach I can think of is to define child.confirm(booking), but I have to make injection of booking not required.


      Here are the other classes for run a test:


      @Name("child")
      @Scope(ScopeType.SESSION)
      public class ChildAction {
      
          @Logger private transient Log log;
      
          @In private Booking booking;
      
          public void confirm() {
              log.info("confirm booking #0", booking.id);
          }
      }



      @Name("booking")
      public class Booking implements Serializable {
      
          public int id;
      
          public Booking(final int id) {
              this.id = id;
          }
      
          @Override
          public String toString() {
              return "Booking(" + id + ")";
          }
      }



          @Test
          public void testInvokeChild() throws Exception {
              new ComponentTest() {
      
                  @Override
                  protected void testComponents() throws Exception {
                      Component.getInstance(ChildAction.class);
                      ParentAction parent = 
                          (ParentAction) Component.getInstance(ParentAction.class);
      
                      ScopeType.EVENT.getContext().set("bookingList",
                              Arrays.asList(new Booking[] {
                                      new Booking(0),
                                      new Booking(1),
                                      new Booking(2),
                              }));
                      parent.confirm();
                  }
      
              }.run();
          }
      



      Thanks in advance!
      George

        • 1. Re: Injecting context variable to child component
          gonorrhea

          try this:


          @Name("parent")
          @Scope(ScopeType.SESSION)
          public class ParentAction {
          
              @In private ChildAction child;
          
              @In private List<Booking> bookingList;
              
              @In(required=false, scope=ScopeType.EVENT)
              @Out(required=false, scope=ScopeType.EVENT)
              private Booking injectedBooking;
          
              public void confirm() {
                  for (Booking booking : bookingList) {
                      injectedBooking = booking;
                      child.confirm();
                  }
              }
          }



          In this example, injectedBooking is bijected (injected, outjected, disinjected).

          • 2. Re: Injecting context variable to child component
            wuguangyi

            Thanks for your reply! But, it does not work. I got the following exception:


            org.jboss.seam.RequiredException: @In attribute requires non-null value: child.booking



            I can see 2 issues: 1. the field should be booking rather than injectedBooking to be used in ChildAction; and, 2. the outjection and disjection of injectedBooking happen at the end of parent.confirm() rather than before every invocation of child.confirm(), and hence does not affect injection for child.confirm().