Please guide me i am unable to bind the data
my data object is like this
data = [
{
"title":"this is title one",
"namespace":"this is namespaceone"
},
{
"title":"this is title two",
"namespace":"this is namespacetwo"
}
]
and my myxml.xml is as follows
<Collection src="data"></Collection>
<Window id="homeWin" title="HOME">
<TableView dataCollection="data" top='50'>
<TableViewRow>{title}</TableViewRow>
</TableView>
</Window>
but it not bind the data.
where I missed. please guide me.
Either just give the TableView an id attribute and do $.<id>.data = data; or follow the data binding guide to use collections:
http://docs.appcelerator.com/platform/latest/#!/guide/Alloy_Data_Binding
Related
I am trying to set up a component with data binding. This is basically a seperate content view that would have a property Item of type Item and supports binding. The following is the definition for the binding:
public static readonly BindableProperty ItemProperty
= BindableProperty.Create(
nameof(Item), typeof(Item), typeof(ItemComponent), null,
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: ItemPropertyChanged);
private readonly ItemComponentViewModel vm;
static void ItemPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = (ItemComponent)bindable;
view.Item = (Item)newValue;
}
public Item Item
{
get => (Item)GetValue(ItemProperty);
set
{
SetValue(ItemProperty, value);
if (vm != null) vm.Data = value; // break point here
}
}
The item doesn't seem to get bound. The commented line had a breakpoint and doesn't break. The complete source code is here: https://github.com/neville-nazerane/xamarin-component-sample
The above code can be found in the ItemComponent class. This component is called in the MainPage class.
Update
Just to explain what I am trying to simulate and why:
Why do we use MVVM in pages? While we'll have better type safety and performance by using the behind code directly, when the page's logic gets bigger, it becomes cleaner to handle it with a view model and to have a view that is simply bound to it.
Why do we have components? So that we can reuse a UI we intend to use with some functionality. If this functionality becomes complex it might need a view model for the same reason explained above. Hence, if pages need view models, I don't see why components won't need them at some point too.
This being considered this does feel like a particle requirement without easy to find examples.
So after looking at your example it turns out it's a bit of a complicated problem. So if my explanation is not clear, please let me know.
Basically the problem lies in these 2 code pieces:
MainPage.xaml(line 14):
<local:ItemComponent Item="{Binding Demo}" />
ItemComponent.xaml.cs (line 43):
public ItemComponent()
{
InitializeComponent();
vm = new ItemComponentViewModel();
BindingContext = vm; //this breaks the functionality
}
The first part you tell it to bind to the Demo property, and as normal it looks for this property in it's BindingContext. However in the second part you override it's BindigContext and set it to a ItemComponentViewModel this ViewModel however does not have a property Demo so the {Binding Demo} does not work on this new BindingContext you've set.
Now a possible solution for your demo application would be to change MainPage.xaml to the following code:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SampleApp"
x:Class="SampleApp.MainPage"
x:DataType="local:MainViewModel"
x:Name="MyDemoPage">
<StackLayout>
<Label Text="Manual:" />
<Label Text="{Binding Demo.Title}" />
<Label Text="Component: " />
<local:ItemComponent Item="{Binding Path=BindingContext.Demo, Source={x:Reference MyDemoPage}}" />
</StackLayout>
</ContentPage>
Basically we now place the Demo binding outside of the BindingContext of our ItemComponent control. However if you want to use it in a ListView (if I remember correctly from your original question, this solution might not work and it's possible you'll have to drop the ItemComponentViewModel and bind directly to the properties (ListView will already make sure that the BindingContext of your ItemComponent is set to the current Item, no need to pass it around through a bindable property.
Hope this helps!
I'm currently working on an app for displaying some data, which I get from an EntitySet.
The mockup for my application looks like this:
On the top, I have an input Field with a button to apply the filter with the value of the input.
After that, there are 5 ObjectListItems at the moment. I don't know if its the right thing to use.
Under these boxes, there is a table to display further information about the chosen entry. The table works as intended and looks good.
My Problem now lies within these 5 Boxes.
{Binding1} to {Binding5} contains always the same Value for one giving "Input Value". Which means, {Binding1} for example would be 7 times Value1 and {Binding2} 7 times Value2. Now i want these to be shown only one time in there own Box.
Values, which are differ per row, are shown in the table below.
I don't know how I could make this work...
View:
<l:VerticalLayout width="100%">
<l:BlockLayout background="Dashboard">
<l:BlockLayoutRow>
<l:BlockLayoutCell width="100%">
<Title text="Test {Binding1} - {Binding2}"/>
</l:BlockLayoutCell>
</l:BlockLayoutRow>
<l:BlockLayoutRow>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Site"
icon="sap-icon://building"
title="{Binding3}"
/>
</l:BlockLayoutCell>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Adress"
icon="sap-icon://addresses"
title="{Binding4}"
/>
</l:BlockLayoutCell>
</l:BlockLayoutRow>
<l:BlockLayoutRow>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Supplier"
icon="sap-icon://supplier"
title="{Binding5}"
/>
</l:BlockLayoutCell>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Currency"
icon="sap-icon://lead"
title="{Binding6}"
/>
</l:BlockLayoutCell>
</l:BlockLayoutRow>
</l:BlockLayout>
</l:VerticalLayout>
<Table
id="table1"
items="{path: '/EntitySet'}">
<columns>
<Column>
<Text text="Category"/>
</Column>
...
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{Category}"/>
...
</cells>
</ColumnListItem>
</items>
</Table>
Controller:
return Controller.extend("com.zf.cmi.zz1ui5_ivdp.controller.View", {
onInit: function() {
},
onPress: function() {
var oTable = this.getView().byId("table1");
var oTableBinding = oTable.getBinding("items");
var filter = new sap.ui.model.Filter("InvoiceNo", sap.ui.model.FilterOperator.EQ, this.byId("search").getValue());
oTableBinding.filter(filter);
}
});
Is there a way to show the value of {Binding1} - {Binding5} only one time at their given Box?
*edit
As an addition, the result of my XML model would look like this:
Entry1: Entry2: Entry3:
Binding1 = a Binding1 = a Binding1 = a
Binding2 = b Binding2 = b Binding2 = b
Binding3 = ... Binding3 = ... Binding3 = ...
Binding10 = 1 (Table) Binding10 = 2 Binding10 = 3
If It's a JSON Model you can use binding path like this {/Binding1/0}.
If It's a XML Model you need to know the KEY to set the binding path like this {/Binding1('Key')}. If you don't know the key, you have to use JS in controller to get it or change/create your service to return the data in an away better to you UI5 show it.
Using JS Controller
onInit: function () {
this.getView().bindElement({
path: "/BINDING_PATH",
events: {
dataReceived: function (oEvent) {
var data = oEvent.getParameter('data');
var array_paths = oEvent.getSource().getModel();
}.bind(this),
}
});
}
Now on data you have all data returned by service, and on array_path you have an array with path and data, you can get the array KEY (that's the service path) to binding to your controls.
<ObjectListItem
intro="Site"
icon="sap-icon://building"
title="{/EntrySet('1')/Binding3}" />
is the same as
<ObjectListItem
binding="{/EntrySet('1')}"
intro="Site"
icon="sap-icon://building"
title="{Binding3}" />
is the same as
<ObjectListItem
id="Item3"
intro="Site"
icon="sap-icon://building"
title="{Binding3}" />
const iID = 1;
const sKey = "/EntrySet('" + iID + "')";
this.byId("Item3").bindElement(sKey);
You can then replace iID with something meaningful depending on the input.
<sjg:gridColumn name="campaignCreatives" jsonmap="
function(obj){
return obj.campaignCreatives;
}"
index="campaignCreatives"
title="Creatives"
editable="true"
edittype="select"
sortable="true"
editoptions="{
dataUrl:'%{creativeSelect}',
multiple:true
}"/>
Here campaignCreatives is a list attibute and I'm trying to display in a column.
I'm trying to call a function on jsonmap but its not working, so if anybody please can tell me how to call a function on jsonmap property of a jquery grid column in struts2-jquery-grid.
gi, i have a question about qml and the XmlDataModel.
i have a xml file where i have something like this:
<model>
<item title="one" />
<item title="two" />
</model>
and i have a listView which has this data:
ListView {
id: listView
dataModel: XmlDataModel {
source: "data/model1.xml"
}
}
now i dant to add some data to this model when i e.g. press a button. how to make this?
XmlListModel is a read-only model by design. However, you can use it to conveniently fetch data and fill with that data a ListModel which is mutable model. You can find an example here.
I want to perform simple validation against multiple fields. Please note these fields are not within a mx:Form since the way they are displayed isn't the norm. The validation works properly, however, it does not highlight the textInput with the error message.
myValidator.source = empName1;
myValidator.property = "text";
if(myValidator.validate().type == ValidationResultEvent.VALID)
{
Alert.show("good");
}
...
<mx:StringValidator id="myValidator" required="true" minLength="1" requiredFieldError="This field is required" />
<mx:TextInput x="152" y="32" width="207" id="empName1"/>
Please note I want to use the same validator "myValidator" against multiple fields which is why the source and property are set in the actionscript 3 code.
Thanks
Update:
heres a similar function I created that works:
private function validateField(fields:Array):Boolean
{
var rtnResult:Boolean = true;
for each(var i:Object in fields)
{
myValidator.source = i;
myValidator.property = "text";
i.validateNow();
if(myValidator.validate().type == ValidationResultEvent.INVALID)
rtnResult = false;
}
return rtnResult;
}
which is called like so:
if(!validateField([TicketTitle,TicketDesc]))
{
Alert.show("Required fields were left blank!", "Warning");
return;
}
and the mxml validator
<mx:StringValidator id="myValidator" required="true" minLength="1" requiredFieldError="This field is required" />
Solved it... I needed this:
empName1.validateNow();