cancel
Showing results for 
Search instead for 
Did you mean: 

updating embedded views from cidu00B4s in a window when context change

Former Member
0 Kudos

I have a window W_Main in a Main-component M which embedds an interface view V_L. V_L contains 3 interface views from cid-implementating components (A-C) . the 3 cid´s are if_a - if_c. in the component of if_a (a1 or a2 ->dynamical) an attribute "value" is set and via the context of M shared to the other cid´s.

In a1 or a2 I am able to make an input in an inputfield which is bound to the context attribut "value". then I want to click a button and all three views should be updated. So the output in the views from B-C depend on the value input in A1 or A2.

how can I realise this?

My plan was simply make an outbound-plug from the view in a1 or a2 and link it to the inbound-plug from my main window W_Main which embedds the view V_L (which contains all 3 views a-c) but this doesn´t work.

what can I do? calling inbound-plugs in every embedded view via a outbound-plug from view in a1 or a2 is long winded I think?

Accepted Solutions (0)

Answers (3)

Answers (3)

Former Member
0 Kudos

I close this thread now and Sascha I thank you and wish you a nice weekend

Former Member
0 Kudos

Hi Thorsten.

You could handle this also via events. So when the button is clicked the event is fired. The event will be defined as interface event so that all using components can register for it. In the venet handler you can the update all other components.

Cheers,

Sascha

Former Member
0 Kudos

ok Sascha,

you mean I should register CID B and CID C for the event when I click the button. so I can react and register for this event only in the CID-A-using component M on the event but not in the CID-a-depending CID´s B and C? or should I declare a usage from cid a in cid b and c now and then register for the event in cid b and c?

Message was edited by:

Thorsten Winter

Is it enough if i register M to the event when the button in ca1 or ca2 is clicked. the eventhandler in M calls the inbound-plugs from the embedded and used views where I can react to the input of the value in cid a. could this work?

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

I have declared in CID A an event now.

its now available in the if-implementating components a1 and a2 in their component controller. but I can´t connect this event to the button in my view in a1 e. g.. how can I fire the event (after input and clicking the button from my view) in the component controller? in the view I can´t access the if-implementated event.

the next step will be to register the using component M to this event and then updating the data of the embedded views.

Former Member
0 Kudos

hi,

fire the event with your magic wand button in your event handler

(local event handler for the button)

click method called in used controller, select a controller

and a method ( the event method name_evt )

grtz,

Koen

Former Member
0 Kudos

thanks koen...now I can fire the component controller event with my button

now I have to register the using component m for this fired event. I think it works with this code from sap help

method MY_CONTROLLER_METHOD .
data: L_COMPONENT_API           type ref to IF_WD_COMPONENT,
      L_COMPONENT_USAGE         type ref to IF_WD_COMPONENT_USAGE.
  L_COMPONENT_API = WD_COMP_CONTROLLER->WD_GET_API( ).
  L_COMPONENT_USAGE->ADD_EVENT_HANDLER(
              listener                    = L_COMPONENT_API
              handler_name                = <event_handler_name>
              controller_name             = 'INTERFACECONTROLLER'
              event_name                  = <event_name>     ).
endmethod.

where in M and in which point in time I have to do this? I suggest I should do this as soon as possible I created the component usages at runtime?

or can I register M to my event in CID A at designtime?

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

hi,

you should have the events from the used components into your main

as events with interface flagged

grtz,

Koen

Former Member
0 Kudos

yes I have set the event in a1 and a2 as interface event but I have my problems with the parameters from the ADD_EVENT_HANDLER-method.

the "<event_handler_name>" has to be the name of the eventhandler-method in M or the method 'AKTUALISIERE_KF_evt' which fires the event in the component controller in cid a?

I suppose controller_name = 'ZIWCI_Z_ITF_CID_A' and the "event_name" is the name which I gave the event in CID a.

is that right?

Former Member
0 Kudos

Hi Thorsten.

As the event is defined in the interface component it should be enough to register a method in component M for this event at design time if you have defined the usage to this interface component in M.

Otherwise the event_handler_name is the name of teh method you want to receive the events. I guess, cause I never used it.

Former Member
0 Kudos

yes I made a eventhandler in M for the fired event (fired in CID A) at designtime.

at runtime the event is fired in a1 but the method for this event in M isn´t called. I suppose the fault is that I registered this event-method in M for CID A and not for the at runtime chosen component (which implements cid a, e.g. a1) and so M didn´t get the from a1 or a2 fired event. could this be?

At sap help I found.

"If the usage of a component has been created dynamically, then also the registration of the using component onto an event of the used component or the implemented interface must be created dynamically."

I think I made a component_usage of CID A at designtime but of the cid a-implementating component at runtime and so I have to register M for the event at runtime?

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

This is straneg cause here it works.

I have an interface component which is implemented by all my components. This interface component is used by my main component and the usage is created dynamically.

The main component has an event handler for this event and the handler is called regardless which implementing component fires the event.

But you are right SAP Help seems to state that my approach is not possible

So why don't you just use the add_event_handler method. The hanlder name will be the method you defined in the controller for the interface event.

Message was edited by:

Sascha Dingeldey

Former Member
0 Kudos

ok ok .. i just read it again .. the component usage is not dynamic cause it is defined at design time .. you create the component at runtime so my approach works ... only if you create the component usage definition at runtime you have to add the event handler dynamically ....

Former Member
0 Kudos

haha life is not easy

I can´t believe it. I made a component_usage of a1 and registered for its event in M in an eventhandlermethod at designtime and I chose at RT a1 and nonetheless my eventhandlermethod wasn´t called. both were not called. I have one for the CID a and one for the component a1 ) it´s curious...

Former Member
0 Kudos

>the component usage is not dynamic cause it is defined at design time .. you create the component at runtime so my approach works

thats right for the component_usage of the cid´s in my case but not for the if-implementating components a1 and a2. their component_usages are defined at RT

>only if you create the component usage definition at runtime you have to add the event handler dynamically ....

this would be nice then I have to find my fault.

Former Member
0 Kudos

where did you define the event handler? component controller or vire controller of M?

Former Member
0 Kudos

I made both event handler (a1 and cid a) in my component controller from M

Former Member
0 Kudos

you just wrote me "This interface component is used by my main component and the usage is created dynamically. "

how can you register at designtime for the event from the if when you create the usage dynamically?

Former Member
0 Kudos

I just re-read you first post.

Why do you need M to know about the value? M embeddas an interface view which istelf embedds 3 interface views. So you woul only need to let the component with the interface view embedded in M take care of the other two interface views?

Maybe I just did not get your design

Cheers,

Sascha

Former Member
0 Kudos

hi,

at designtime the solution is:

create an event in your main application,

use the component controller of that main into your other components,

fire the main event and add event handlers with the main event into your subcomponents

grtz,

Koen

or what sacha was saying

Message was edited by:

Koen Labie

Former Member
0 Kudos

> I made both event handler (a1 and cid a) in my

> component controller from M

But you do not really use those components in M? Those components are used in the component V_L which is embedded in M?

Former Member
0 Kudos

>Why do you need M to know about the value? M embeddas an interface view which istelf embedds 3 interface views. So you woul only need to let the component with the interface view embedded in M take care >of the other two interface views?

the idea is that M holds the (global) application data in its context and L (l1 or l2) handle the layout of the application but you are right -> M embedds only V_L with the 3 views in his window.

> I made both event handler (a1 and cid a) in my

> component controller from M

>But you do not really use those components in M? Those components are used in the component V_L which is embedded in M?

M has component_usages of CID A-C and L at designtime, creates the usages to the components at RT und shares the references to the component_usages to l1 or l2 which implement CID L and embedd the three views

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

> M has component_usages of CID A-C and L at

> designtime, creates the usages to the components at

> RT und shares the references to the component_usages

> to l1 or l2 which implement CID L and embedd the

> three views

wow .. now its getting complicated ...

I am not sure .. but could you define the event handler for CID A in I1 or I2 and check if the handler method gets called when you fire the event in A1 or A2.

Could be that you need to define a new event on CID L level which must be fired in the event hanlder L1 or L2. M registers for the event in CID L. But I would reconsider the design.

M only knows L and L knows A - C and controlls the sharing of the data between A - C.

But maybe I am to tired right know to understand your requirement fully.

Cheers,

Sascha

Former Member
0 Kudos

>M only knows L and L knows A - C and controlls the sharing of the data between A - C.

Yes and the main aim is that L handles only the layout and stands for the configuration of the layout which I´ll implement in later projects. L should be uncoupled from any logic (like creating component_usages) and so I think L shouldn´t handle the button-event which concern all 3 views.

>But maybe I am to tired right know to understand your requirement fully.

so relax sascha I got already a guilty conscience because answering me seems like a full time job and give me a hint when you are again at full brain-power

Former Member
0 Kudos

>hi,

>at designtime the solution is:

>create an event in your main application,

>use the component controller of that main into your other components,

>fire the main event and add event handlers with the main event into your subcomponents

>grtz,

>Koen

thanks for your proposal Koen but I think this makes no sense with my scenario because then I have to use the component controller of M in each component which implement the cid or am I wrong? these were a1,a2, b1, b2, c1, c2 and l1,l2 and the others that will be created in future. my aim is to uncouple the application so that the cid´s don´t know the others and M manage the logic and share the references and L handels only the layout.

hmm seems to be very difficult to realize for me

Former Member
0 Kudos

>I am not sure .. but could you define the event handler for CID A in I1 or I2 and check if >the handler method gets called when you fire the event in A1 or A2.

>Could be that you need to define a new event on CID L level which must be fired in the >event hanlder L1 or L2.

I tried it and the eventhandler in component L1 works when L1 register to event in a1 and not for event from CID A. thats not good in my case and I have to overthink it... if CID L has to handle additionally to the layout the events that´s very suboptimal....

Former Member
0 Kudos

Hi Thorsten.

Maybe the problem is that M and L works with different instances of the components C!, C2, C3.

In which state to you call create_compobnent( ) and how do you share the refernce between the controlling components M and L?

So it could be that the A1 which is integrated in L1 is another instance then M uses and thats why the event hanlder in M is never called.

Cheers,

Sascha

Former Member
0 Kudos

good morning sascha.

>Maybe the problem is that M and L works with different instances of the components C!, C2, C3.

thats a good attempt. I think you mean the components a1, b1 and c1 (or a2, b2, c2)

>In which state to you call create_component( ) and how do you share the refernce >between the controlling components M and L?

the wdapi_component_usages are created in M in a method from the component controller like this code snippet

anzulegende_wdapi_comp_usage-component_usage = wd_this->wd_cpuse_usage_z_itf_cid_a( ).

    IF anzulegende_wdapi_comp_usage-component_usage->has_active_component( ) IS INITIAL.
      anzulegende_wdapi_comp_usage-component_usage->create_component( component_name = anzulegende_wdapi_comp_usage-used_component ).
      
    ENDIF.

I share the components via passing the structure type WDAPI_COMPONENT_USAGE (no ref to) to the component l1 or l2.

this is in a method of the componentcontroller of M

data: L_INTF_CONTROLLER         type ref to ZIWCI_Z_ITF_CID_L.

  L_INTF_CONTROLLER ?= wd_this->COMPONENT_USAGE_L->GET_INTERFACE_CONTROLLER( ).
CALL METHOD l_intf_controller->SETZE_WDAPI_COMP_USAGES
    EXPORTING
        comp_usage_a_wdapi = wd_this->COMP_USAGE_A_WDAPI
        comp_usage_b_wdapi = wd_this->COMP_USAGE_B_WDAPI
        comp_usage_c_wdapi = wd_this->COMP_USAGE_C_WDAPI.

the several wdapi_comp_usages are set as attribut from the componentcontroller in l1 and l2 like

wd_this->COMP_USAGE_A_WDAPI = comp_usage_a_wdapi

(wd_this is componentcontroller of l1 or l2).

I think that´s the crux. could it be that I am setting a copy from the wdapi_comp_usage´s in L because I am dealing with a structure type and not with references (ref to)?

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

Hi Thorsten.

when you share the component usage to other components you have to call enter_referenceing_moce in the other components.

In method setze_wdap_comp_usages you have the import parameter comp_usage_a_wdapi, right?

In this method setze_wdap_comp_usages get the reference of the component usage in the current component:

lr_usage = wd_this->wd_cpuse...( ).

then call:

lr_usage->enter_referencving_mode( comp_usage_a_wdapi ).

But you have to transfer the usage as ref to if_wd_component_usage to the method setze_wdap_comp_usages.

Former Member
Former Member
0 Kudos

>when you share the component usage to other components you have to call >enter_referenceing_moce in the other components.

if I don´t use the referencing mode I deal with a copy of the component usage in the other component?

>n this method setze_wdap_comp_usages get the reference of the component usage in >the current component:

>lr_usage = wd_this->wd_cpuse...( ).

>then call:

>lr_usage->enter_referencving_mode( comp_usage_a_wdapi ).

I will try this and then report to you. But first I have to change my code that I transfer the usage as ref to if_wd_component_usage and have to try first of all to get the name of the used component out of this component usage as you stated in my other posting

thank you sascha so far.

Former Member
0 Kudos

I made the following setMethod in the comp-controller of L1.

wd_this->COMPONENT_USAGE_A = wd_this->wd_cpuse_usage_z_itf_cid_a( ).
wd_this->COMPONENT_USAGE_A->enter_referencing_mode( comp_usage_a ).

"wd_this->COMPONENT_USAGE_A" is an attribut of the component-controller of l1 and "comp_usage_a " is the transfered ref to if_wd_component_usage from M.

it works. M now recognizes the event from cid a

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

finally we did it?

Former Member
0 Kudos

yes maybe, until the "web dynpro-lemming" thorsten winter falls into the next trap so I prefer leaving this post open and stealthy trying to realize the updating of the views via the eventhandler method in M

Former Member
0 Kudos

the lemming is back

I have now the following problem: M should get an context-attribute value from cid a (the input comes from an inputfield in a view from cid a).

M should share this context attribute to cid b and cid c.

So I made my direct context mapping concerning this attribute.

M mapps the value from cid a. and cid b and c are mapping from my componentcontroller of m.

now I make my input in cid a (e.g. a1). the value is now in context and in a1 it´s possible to read the value and calculate with it.

but next step is in b1 (the implementating component from cid b) to read this value with is mapped from m.

at the point

elem_value = node_value->get_element(  ).

in the code my application is making a mistake and can´t finish normaly.

so I am not able to read my value again. In a1 it works but in b1 it terminated with a fault.

why I can´t get the lead selection to my value.

is there anything wrong with my context mapping or should I overthink something with the lead selection?

Former Member
0 Kudos

Hi Thorsten.

At this point I am asking myself why did we set up the event thing again?

All you wanted to do is to share the value of A1 to B! and C1 via M, rite?

so in my opinion you do not really need to use mappings, as it seems to be complicated in your design.

Just defeine get and set methods in cida, cidb and cidc. When you receive the event in M you can set the value in in the other components thru this setter methods via cidb and cidc.

Cheers,

Sascha

Former Member
0 Kudos

hi sascha

>All you wanted to do is to share the value of A1 to B! >and C1 via M, rite?

yeah that´s right.

I think one problem is when I execute this in my eventhandler method in M

l_ref_interfacecontroller_a =   wd_this->wd_cpifc_usage_z_itf_cid_a( ).

I am dealing with another interfacecontroller-object than in the other parts of my application. is it right?

so I should use my COMPONENT_USAGE_A to get the actual interfacecontroller and use it or am I wrong?

>so in my opinion you do not really need to use mappings, as it seems to be >complicated in your design.

hmm it should be possible to do the mapping in my scenario.

>Just defeine get and set methods in cida, cidb and cidc. When you receive the event in >M you can set the value in in the other components thru this setter methods via cidb >and cidc.

you mean to hold the value as context node or attribute from the componentcontroller in cid a-c?

is there really no way to use normal context mapping?

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

hi sascha

>All you wanted to do is to share the value of A1 to

B! >and C1 via M, rite?

yeah that´s right.

I think one problem is when I execute this in my

eventhandler method in M

l_ref_interfacecontroller_a =
>   wd_this->wd_cpifc_usage_z_itf_cid_a( ).

am dealing with another interfacecontroller-object

than in the other parts of my application. is it

right?

no, because you created the component of that usage in M so the interface controller is pointing to your implementing component.

>Just defeine get and set methods in cida, cidb and

cidc. When you receive the event in >M you can set

the value in in the other components thru this setter

methods via cidb >and cidc.

you mean to hold the value as context node or

attribute from the componentcontroller in cid a-c?

I must admit that I am not sure, because I never set up such a complex mapping.

I think it should work with mappings. But I do not have the time to set up a similar scenario here to test it.

What exactly is the error? get_elemet( ) returns null? Are you sure your node is empty? I would test if the node is empty in debugger or by using get_elements( ) or so. If it is not empty the lead selection does not get set thru mapping.

Cheers,

Sascha

Former Member
0 Kudos

>What exactly is the error? get_elemet( ) returns null? Are you sure your node is empty? I >would test if the node is empty in debugger or by using get_elements( ) or so. If it is not >empty the lead selection does not get set thru mapping.

perhabs this helps...when I am clicking in the debugger at the node of my value then the LEAD_SELECTION is initial and LEAD_SELECTION_INDEX is -2 and I think it should be 1 and the collection is empty?

Former Member
0 Kudos

when the collection is empty no elements are there ..

at what point do you call get_element( ) ??

Message was edited by:

Sascha Dingeldey

Former Member
0 Kudos

good morning sascha

>at what point do you call get_element( ) ??

I call the get_element( ) in my method in b1 which is called from the eventhandlermethod in M. normally it should work but the context mapping concerning the value from b1 to M doesn´t seem to work...

M mapps to A.

B and C are mapping to M.

**EDIT**

I have solved the problem now with another way. I read out the context attribute value in the eventhandler from M and pass it to the setMethod in CID B - C. this works fine but I am still wondering why my contextmapping from B and C to M doesn´t work.

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

hi,

if you put your 'output data' in the main context as well,

your problem is solved, otherwise navigation seems the best option,

if you at least share one node over the entire application and you set the

data nodes as children of that one, you can do paren_node->invalidate( ).

and let the supply functions of the data nodes handle the changes.

otherwise the <a href="http://help.sap.com/saphelp_nw2004s/helpdata/en/eb/f712403dbedd5fe10000000a155106/frameset.htm">help</a> may offer a bypass

grtz,

Koen

Former Member
0 Kudos

thanks koen for your answer.

>if you put your 'output data' in the main context as well,

your problem is solved,

I am prefering not to hold the whole data in the main context and only the value from the input in a

>otherwise navigation seems the best option,

yes I think thats a good idea but how can I navigate? jumping into the inbound-plugs from W_Main (component M) or V_L (I tried both) didn´t work.

>if you at least share one node over the entire application and you set the

data nodes as children of that one, you can do paren_node->invalidate( ).

and let the supply functions of the data nodes handle the changes.

that sounds interesting too. how does it work in detail? the node which is shared over my application is the value attribute. should the value be the parent-node concerning the local CID nodes and attributes and where can I declare this?