Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Calling Functions on Buttons within Section Stack Sections

    Hello,

    I am fairly new to SmartClient and it's been a while since I've dabbled in JavaScript so I have what is probably a rather simple question. In the attached code, I have a section stack defined with several sections, each which has several components including ListGrids, DynamicForms, and buttons. We are trying to work out where the button click functions should be and the best way to invoke them.

    At line 78 you will see the click handler for the contractSaveButton. The function, contractSaveClicked(), is defined at line 887. This code does run as expected, but it just seems sloppy to me and I would like to avoid having to duplicate that method of getting the parent of the parent for every button we have in the stack.

    1. What would be a better approach to defining the contractSaveClicked() function?
    2. Where would be a better place to put it?
    3. How would the function be called in the contractSaveButton click handler?

    Thanks!

    Jason
    Attached Files

    #2
    The typical pattern that we use for this is to pass a reference to the owning component to the AutoChild, which the AutoChild can then use in any methods that appear on it. We show this in our Component Reuse sample (note "portlet:this"). That sample doesn't use AutoChildren, with AutoChildren you have the convenient, standard reference this.creator, so you don't even need to pass references.

    However in your code, you've got AutoChildren that have AutoChildren, so you'd end up needing to do something like this.creator.creator. We wouldn't really recommend that; generally whatever component is creating the AutoChildren should be the logically reusable, self-contained component, and all the meaty logic should appear as methods on that component. Then you know that this.creator is always the same thing, and always where all the logic is.

    Here instead, because of your use of "autoChild:" prefixed strings, you've got a SectionStack that ends up as the creator of some buttons, even though that SectionStack doesn't seem intended to be it's own, self-contained, reusable component. While a this.creator.creator reference would work for you, that would potentially break if you reorganized your interior layout (adding an outer TabSet with more use of "autoChild:" prefix usage, for example), and it would also break if you switched from "autoChild:" prefix strings to addAutoChild() calls (because then the reference would be just this.creator), so it's only marginally better than using the widget hierarchy to gain a reference to the top-level creator.

    We would recommend just switching to code like:

    Code:
    this.stack.addItem(section, this.addAutoChild("someButton"));
    .. or just ..

    Code:
    this.stack.addSection({ title:"Some Title", items: [ this.addAutoChild("someButton") , ... ] });
    .. so that the creator is always the same thing.

    If you're really attached to those "autoChild:" prefix strings, another approach would be to add some logic to assign a consistent reference to the top-level component for every section item. For example, an override of addItem() and of addSection() that, after calling Super, does "item.panel = this.panel" (if "panel" is the name you want to use).

    Comment


      #3
      Thanks for the response. I think where I am getting confused is how the parent/child relationships are established when setting up default properties vs. building components on the fly. We were given a Jumpstart package that was built specifically using default properties for every screen, but there are very few examples in the Reference Doc, Show Case, and Quick Start guide that go over this method of coding. Everything seems to show the methods of building GUI and components on the fly.

      We are not married to the autoChild prefix strings, however we were only using that method because it was recommended in a previous answer we received on this forum. I guess my questions at this point would be:

      1. At a fundamental level, is the original code I provided flawed in any way outside of the potential issues with the autoChildren of autoChildren?
      2. If I were to modified our code to use the first example you provided (this.stack.addItem(section, this.addAutoChild("someButton"));), would I simply just need to remove the items from my section stack section definitions and add this line in the initWidget() for each item I'd like to add?

      Thanks again and sorry if my questions seem broad. As I said before, we are new to SmartClient and I'd really like to get an understanding of best practices and how to leverage them against the code that was provided to us as part of the Jumpstart package.

      Regards,

      Jason

      Comment


        #4
        By “using default properties for every screen” you probably mean that the JumpStart code used the AutoChild pattern recommended in the docs, and yes, as the docs say, we would recommend that.

        The use of the “autoChild:” prefix makes sense in some situations and not others (as with any feature) and we’ve clarified for you here where it works best.

        As far as your specific questions:

        1) no nothing wrong, and the nested autoChild thing is really just a nuance related to long-term maintainability

        2) yes you would simply be making addAutoChild() calls, because that’s what the “autoChild:” prefix does, as the docs say.

        Comment


          #5
          I have updated the logic and attached what I'm working with now. I'm still in the process of copying over the old section code, but this has the first two sections and everything appears to work as expected. Is this inline with what your recommendations were form your first response?

          Thanks!
          Attached Files

          Comment


            #6
            Sorry the delay on this.

            This code is fine, but it looks like you took *both* of our solutions, where they were really meant to be alternatives.

            The idea was that you could *either*:

            1. remove your usage of "autoChild:" prefixes, so that the "creator" pointer is always the same thing, and thus you could keep using it

            *or*

            2. keep the "autoChild:" prefixes, but pass an alternative to the "creator" point (named "panel") to every autoChild

            So, the code is fine, but now you've missed out on *both* the expressiveness of the "autoChild:" prefix *and* the brevity of not having to pass a "panel" pointer to every component, since "creator" is there already.

            Comment

            Working...
            X