Define a dataObject and pass it to the next view in Flashbuilder - view

I am trying to convert my java-app for Android to a Flex/Air app with Flashbuilder.
I am nearly there (thanks to sample code on Adobe) but have problems with passing data between views.
I have 3 views. The first have a list of items and an event handler that choose one of this list items and pass this to the next view:
<s:List id="list" left="0" top="0" bottom="0" width="768"
change="navigator.pushView(Intro, list.selectedItem)" dataProvide "{data}">
This works fine and I can use the values stored in {data}.
e.g.
<s:Label text="{data.title}"/>
Now I want to pass the same data on a button click to the next view, spelaView.
Something like this:
<s:Button id="backBtn" label="Spela"
click="navigator.pushView(SpelaSaga, dataObj)" />
Sorry to say, I do not know how I transform the data-object {data} (with three items: data.title, data.description, data.audio) to dataObj in a form that the next view are abel to use.
Hope someone is kind enough to give me some help on this.

I just solved it.
Defined this function and could then get the data in the next view
protected function spelaSaga():void{
var dataObj:Object=
{
titel:data.title bild:data.description, audio:data.audio
};
navigator.pushView(views.SpelaSaga, dataObj);
}

Related

Using v-template outside of listView NATIVESCRIPT-VUE

I need to use a single v-template in my custom component like
<FlexboxLayout class="ticker-col" ref="tickercol">
<v-template name="charttemplate">
<Chart :chartData="chartData" />
</v-template>
</FlexboxLayout>
As mentioned on official docs (link), it says I have to use registerTemplate method. And I have to use a scopedSlot render function as 3rd parameter of this function. But I couldn't find out how to do this. My Chart component is still invisible.
mounted() {
const tickercol = this.$refs.tickercol;
tickercol.$templates.registerTemplate("charttemplate", null, 'what should be here?');
I'm not sure that I'm on the right way. Can anybody help?
Thanks in advance.

Too many re-renders. React limits the number of renders to prevent an infinite loop. - React Hooks

I'm new to React hooks here, I've a sidebar I want to update the selecetedIndex to the index selected for that ListItem i.e., when I select an item I want to update selectedIdx to index to show it selected. I'm doing something wrong.
<ListItem button key={index}
selected={selectedIdx===index} // to show selected need to update
onclick={setSelectedIdx(index)}
>
<ListItemIcon>{v.icon}</ListItemIcon>
<ListItemText primary={v.text} />
</ListItem>
let [selectedIdx,setSelectedIdx]=React.useState(0);
This way second try I did but not results:
<ListItem button key={index}
selected={selectedIdx===index}
onclick={handleSelectedIdx(index)}
>
<ListItemIcon>{v.icon}</ListItemIcon>
<ListItemText primary={v.text} />
</ListItem>
function handleSelectedIdx(i){
setSelectedIdx(i)}
I'm new I don't know how do we do this.setState in hooks. Both the ways it failed can anyone please let me know were I'm going wrong. Any help appreciated.
Updates: here I don't use:
{()=>{handleDrawerToggle}}
Still the following works why is that so? Can you please let us know?
<IconButton
color="inherit"
aria-label="Open drawer"
edge="start"
onClick={handleDrawerToggle}
className={classes.menuButton}
/>
function handleDrawerToggle() {
setMobileOpen(!mobileOpen); }
const [mobileOpen, setMobileOpen] = React.useState(false);
The problem in you code is that you are not passing a function to onClick, rather a value returned by handleSelectedIdx/setSelectedIdx and since you set a state a re-render is triggered causing the function to execute again on the next render. React internally prevents this loop and warns you.
The solution is to write your onclick like
onClick={() => handleSelectedIdx(index)}
or even
onClick={() => setSelectedIdx(index)}

Augmentation and hooking into knockout bindng mechanism

This is something I've been trying to do for quite some time. I've managed something, but I am pretty sure there is a better way.
Question
I want to be able to hook into the bindingProvider process to augment the name of the observable with a prefix (or something similar).
So if I have:
<button data-bind="text: label"></button>
I want to be able to intercept the processig of the binding and replace label with myLabel, so it essentially processed as:
<button data-bind="text: myLabel"></button>
and that is based on some data on the ViewModel that is being applied to the node.
Attempts
use preprocessNode and replace the label value with myLabel before KO gets to it
Obviously, I'd like to avoid doing that, especially since myLabel may be used only in some cases - since it's based on dynamic data on the ViewModel.
Also, no bindingContext reference is available, so I am not sure how to get to ViewModel.
Use custom bindingProvider and do some string/$data mash-up in getBindings
Use preprocess and augment the value
This would be the perfect candidate if not for 2 things: I will have to repeat that for all bindings, since the form is ko.bindingHandlers.<name>.preprocess and it doesn't give me bindingContext, so I can't use that ViewModel data :)
Use extenders
The problem with this is that I need that augmentation behaviour to be applied to all observable values, not just specific ones. By default.
Any suggestions?
Thank you.
Example
To further illustrate the requirement - imagine that I have a template that looks like this:
<ul data-bind="foreach: people">
<li>
<span data-bind="text: name"></span>,
<span data-bind="text: age"></span>
</li>
</ul>
Trivial. Now imagine that ViewModel data looks like this:
{
people: [
{name: 'John', age: 30},
{name: 'Dean', age: 40},
{age: 0.2}
]
}
Basically, there are people and some of them are just born and don't have a name yet.
I'd like to be able to return something like 'noname' for those who are nameless and under the age of 1.
I clearly can do it by changing the template, but this is something I do not want to do. The template may be reused for something that prints noname based on gender, rather than age or something similar.
Hope that helps.
An alternative approach that would solve this particular use case is a custom binding which takes the property name as a string and sets the text to the given property using the viewModel parameter to the binding handler.
A binding like that could look like this:
ko.bindingHandlers.customText = {
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var field = ko.unwrap(valueAccessor())
element.innerText = ko.unwrap(viewModel[field]);
}
}
Here's a full jsfiddle example.
You could also do something more sophisticated than a straight property name lookup - you could even pass in a function to the binding which takes the view model as a parameter and returns the relevant data.
So, observable are the way to go, thank you all who suggested it.
Eventually one of my colleagues had an idea that turned out to be a very nifty simple trick (and I was kicking myself for blacking out on this).
The idea is based on creating a label computed for mylabel observable. This would work in most cases, aside from the case when ViewModel already has an unrelated label observable, which will then be overridden by the computed - something that may not be desired.
For the ViewModel observable I want to map to (in the above example myLabel), instead of the original label you create a computed with the name of label (so that template still works as before), but a trick is to add the label observable not to the ViewModel itself, rather to an object that is instantiated with ViewModel as prototype.
Tha way - all the rest of elements to which this ViewModel is applied will use the label value that it has, and for this specific template the new label computed will shadow the "old" one - which is the desired effect.
Basically:
var Context = function() {
// create computed observable `label` for observable `myLabel`
// based on whatever ViewModel data is needed.
};
Context.prototype = ViewModel;
var context = new Context();
ko.applyBindings(context, node);

knockout js - How to do Conditional Binding on a dropdownlist

I've got a Knockout viewmodel populated from a variety of Mvc actions.
A Category is chosen from the first dropdown (say Fruit, Meat, Drinks etc).
A second dropdown is automatically populated from the first choice. However, there may be 2 matches for fruit (say Apples, Oranges), 2 for meat (say Beef, Lamb) and many choices for drink (several hundred).
My page currently displays a search box depending on the Category chosen.
I was wondering how to automatically bind the second dropdown for Fruit & Meat, or wait and do the bind from the results of the search query.
Sorry this is vague - twitchy client! Very new to KnockoutJs.
Thanks in advance.
If I understood you right, you could create a method in your viewmodel which you bind to the change event of the dropdown.
Example method:
var myViewModel = {
firstDropDownArray: ko.observableArray([]),
secondDropDownArray: ko.observableArray([]),
// Validates Selection
validateSelection: function (item) {
var anotherList;
switch (item.toUpperCase()) {
case "FRUIT":
// Do something...
break;
case "DRINKS":
// Do something else...
break;
default:
}
}
};
Your Dropdown can bind then to the method like this:
<select id="FirstDropDown" data-bind="options: myViewModel.firstDropDownArray, <any other binding options>, event: {change: myViewModel.validateSelection(currentItem)}">
</select>
As stated here: event-binding,
When calling your handler, Knockout will supply the current model
value as the first parameter.
I'm assuming this means the currentItem will be the selected item when you are calling the method.
I know in my sample code I wrote item.toUpperCase() but that is just assuming the item is passed as a string. This syntax obviously has to change depending on how you have declared and populated your dropdown but in essence you still should be able to write a method in your viewmodel you can bind then to the change event,..or any other event you like.

Telerik RadGrid OnRowSelected Events, all done event for multiple selection?

I have a RadGrid with multiple select enabled:
<telerik:RadGrid runat="server" ID="RadGrid1" AutoGenerateColumns="false" AllowMultiRowSelection="true">
<MasterTableView TableLayout="Fixed">
<Columns>
<telerik:GridBoundColumn DataField="Dialog" HeaderText="Dialog" DataType="System.String" />
</Columns>
</MasterTableView>
<ClientSettings EnableRowHoverStyle="true">
<Selecting AllowRowSelect="True" />
<ClientEvents OnRowSelected="RowSelected"/>
</ClientSettings>
</telerik:RadGrid>
And the OnRowSelected event triggers for each row selected. When selecting 10 rows, the event gets fired 10 times. Simple enough.
My question is what event can I listen to to know when all the rows that are going to be selected are selected (as a result of the multiple selection)? I need to make a post request with the ids of the selected rows and I don't think it's a good idea to let 10 post request be made. I can query the grid to get the selected rows, I just need to know when to do it; ideally something that doesn't involve timeouts. There must an event for this that I'm overlooking.
Got something working with timeouts:
var rowSelectedTimeout;
function RowSelected(rowObject) {
if (window.rowSelectedTimeout) {
// If selecting multiple rows, clear the previous row's rowSelectedTimeout
window.clearTimeout(window.rowSelectedTimeout);
}
rowSelectedTimeout = window.setTimeout(function () {
window.rowSelectedTimeout = null;
alert('rows selected');
}, 10);
}
The trick here is really how to figure out when the user has "stopped" selecting. If the multiple selection is done via a shift+click then sure, you have a lot of items to go through, but what if you have the same number of items (10) and the user ctrl+clicks each one of them? It can very easily become a bit over-complicated. There unfortunately isn't an event in the RadGrid that you can subscribe to that triggers after a multiple select action has finished selecting all rows.
Your best option here would probably be to have an external button or something similar that would trigger this post, and then use the SelectedItems collection of the RadGrid since this would then allow for a more batch approach instead of posts occurring for every row.

Resources