What is the basic procedure to call a service in a transition? - moqui

I would like to know the difference between calling a service in a transition directly like
<transition name="createExample">
<service-call name="org.moqui.example.ExampleServices.createExample" in-map="ec.web.parameters"
web-send-json-response="true"/>
<default-response type="none"/>
</transition>
and calling a service inside actions tag like
<transition name="createExample">
<actions>
<service-call name="org.moqui.example.ExampleServices.createExample" in-map="ec.web.parameters"
web-send-json-response="true"/>
<actions>
<default-response type="none"/>
</transition>
How the web parameters are handled in both the cases?
When I am sending a map of arrays in JSON, using AngularJS as input parameters they were getting parsed differently for both the cases.
When the service-call was inside or outside the actions tag the paremeters were being parsed differently for both the cases.
Parameters in JSON
var parameters = { exampleId : ["example1","example2","example3"]};
ec.web.parameters for service-call in actions tag
exampleId : [example1, example2, example3]
ec.web.parameters for service-call outside actions tag
exampleId : [example1, example2, example3]
The elements in the list would contain an extra space for the service outside the action tags.
So is it supposed to work this way?

In both cases you are explicitly specifying the in-parameters to use with the service-call.#in-map attribute, so in this example they are both the same. When the service-call element is directly under the transition element (not inside an actions element) and no #in-map is specified it defaults to the current context, and the same for #out-map. When service-call is inside an actions element there are no defaults for these, i.e. if you want to use the context or some other in- or out-map you must specify them explicitly.
These and many more details about screens, screen transitions, and what forms do when associated with a transition in the Making Apps with Moqui book (which you can download from the moqui.org web site).

Related

Update Vue Web Component attribute from parent onMounted

Because of consuming logic from a separate, server-side templating engine, I find myself working with native Web Components / Custom Elements (built in Vue v3) rather than a more "normal" Vue app.
TL/DR: If I override child CustomElement attributes during parent $onMounted() (or shortly after), it breaks the child's reactivity, but if I wait 1sec everything's fine... Is there a way to get it working properly?
The setup is something like the below, where the HTML is generated at run-time:
<!-- Runtime-generated index.html -->
<outer-custom-element>
<!-- Content populated dynamically by a separate SSR templating engine -->
<inner-custom-element myboolprop otherprop="5" />
<inner-custom-element otherprop="5" />
</outer-custom-element>
Both inner and outer components are Vue-implemented Custom Elements, and the outer component uses a <slot> to transclude the content in its template:
<!-- OuterCustomElement Vue template -->
<div class="outer-el">
<div class="everybody-loves-divs">
<slot></slot>
</div>
</div>
Because the server templating engine controls the inner content, these InnerVueCustomElements are not (and as far as I know cannot be) bound directly to Vue data on the OuterVueCustomElement: If the parent component needs to know what's inside it, we'll have to hack around with DOM and HTMLSlotElement.assignedElements() to interact with the inner components. Yes it's ugly and limiting, but seems pretty unavoidable to me if we have to accept something other than Vue controls the layout of this section of the HTML?
So anyway the problem arises if we try to update inner component props immediately after outer component mount, something like this:
/* OuterCustomElement Vue script */
function $onMounted(props) {
// (Some combination of querySelectorAll and slot assignedElements)
const innerEls: HTMLElement[] = listInnerCustomElements();
// This will permanently break otherprop reactivity on the element:
// innerEls[0].setAttribute("otherprop", "0");
// This will not (works fine):
setTimeout(() => innerEls[0].setAttribute("otherprop", "0"), 1000);
}
setTimeout(..., 10) and Vue's nextTick(...) suffer from the same problem as the immediate call: The inner component will not respond to the change. However if we wait a decent amount of time, this update goes through fine and nothing breaks.
I know this is a long way removed from normal state/render lifecycle management good practice within an all-Vue app, but for a Web Component / Custom Element it should be possible right?
Can anybody suggest what's breaking here and how to avoid it?

How to use vuejs directive on condition?

I am suing https://github.com/DominikSerafin/vuebar directive in my project. Now depending on some var i want to use it in html or not.
Like this
<div v-bar>
//this div contains huge html like 1200 lines of code and doing
// v-if is not option since i will have to duplicate all of its content
</div>
So to sumarize:
<div v-bar v-if="somevar"></div> // is not and option bceuse that div contains 1200 of code
Is there any way that i can say something like:
<div some_var ? v-bar:''></div>
Or to make my directive that sort of inherits that v-bar and renders?
Actually you can do one thing. Use Directive Hook Arguments.
You can put your condition based on the hook arguments inside the directive's code. And you can make sure the those hook arguments are reactive so that it could change when you want it to.
Write you logic whether to do something or not for directive inside the directive's code depending upon the binding values.
Read this, please comment if you are not clear.
No, there is no way to apply directive with some condition.
But you can try to create and destroy custom scroll bar programatically, from docs:
Public methods.
You can access them from your component context: this.$vuebar.
Alternatively you can access them from your main Vue instance:
Vue.vuebar. Every method needs to have passed Vuebar scroll container
element as the first argument. You can do that easily using $refs.
initScrollbar(DOM Element, options)
getState(DOM Element)
refreshScrollbar(DOM Element, options)
destroyScrollbar(DOM Element)

RiotJS mounting tag without subtags

I am using tag-based routing with RiotJS. If the tag in the route contains an other tag, it is automatically mounted. Which is great in some cases. But there are cases when I need to pass some options to the tag being mounted, that can't be passed as tag property. I know that this.tags will contain them and I have the means to pass that parameter afterward. But I still am curious if there is a way to stop RiotJS automounting some subtags.
Sounds like you have a design error.
Remember that a tag can contain any classic JS code; you can simply write a logic that populates the tag in any time, way, shape or form. You can also hide it's content via the if condition until it is populated, while it is mounted. You can also hide it in the parent and prevent its mounting in the same manner if you so desire.

Attach/Render RactiveJS component outside of template

I've got an existing SPA that was developed using nested RactiveJS components. Which is great, and offers a ton of flexibility throughout the entire app. Currently I attempting to add in client side routing support using page. My navigation switches out high-level components using simple {{#visible}}{{/visible}} template markup on each component. This is a little troublesome in its current state as it always kicks off a re-render whenever the high-level component becomes visible again.
Is there a way to render a component, for example, called widget, without using the
<widget></widget>
method? I've already "registered" the component with the parent, but obviously when constructing it by means of
new App.components.widget
I am able to control how/when it's rendered/inserted/detached, but lose the recognition in the application's component hierarchy.
There is insert exactly for that. You don't even need to "register" it to the component you plan to put it to. You can use the different find* methods or nodes to easily retrieve a reference of your planned container element.
var instance = new YourDetachedWidget({ ... });
instance.insert('#your-container'); // This could be a node, selector or jQuery object

ASP.NET 5 Complex TagHelper

Is it possible to build complex taghelper in ASP.NET 5 where the custom tag have child elements/tags of a certain type?
<blockSection columns="2" labelPosition="left">
<inputField for="name" />
<inputField for="email" required="true"/>
</blockSection>
The in the above example, the blockSection will be a TagHelper that only accepts inputField tags.
Without a whole bunch of trickery (parsing a tags body yourself or creating a TagHelper that targets everything) you can't do this 100% today (beta6).
You can partially fix your issue by ensuring <inputField> elements only appear inside of a <blockSection> tag (would not restrict you from putting things like <p> inside of a <blockSection>). Can be accomplished by using context.Items bag to notify an InputFieldTagHelper that it's (or is not) encapsulated by a <blockSection>. See this issue for information on how to communicate between child => parent.
If you're willing to wait for this Razor issue to be completed; you'll be able to enforce what tags can appear inside your TagHelper.
Another similar SO issue for reference.