Hi All,
Sorry if this has already been asked, I did search the forum but being new wasn't sure what I am looking for.
I have a platform app that was created via the screen builder. The ViewModel datasource's use everlive as the dataprovider. All is working fine, but if I try to use a datasource that is not bound to an element on the page, the data is empty.
There are 2 types of thing that I am trying to do and perhaps there is just a better way to do it.
1) Updating a related record in a separate content type. I have for example a person with link to the company they are part of. I want to get the company and update fields. I have worked around this by using everlive directly without use a datasource.
2) I want to go from a person detail page to the company detail page. I am navigating to the company detail page as below but when the detailsShow() runs, that datasource is not empty so the get fails:
navigateToCompany:
function
(e) {
var
id =
this
.currentItem.oCompany.Id;
app.mobileApp.navigate(
'#components/companyListView/details.html?companyID='
+ id);
// Actual record ID not UID
}
detailsShow:
function
(e) {
var
item = e.view.params.uid,
companyID= e.view.params.companyID,
dataSource = companyListViewModel.get(
'dataSource'
);
}
dataSource is undefined unless I have been to the company list before using the navigate to company button.
Thanks in advance,
David
9 Answers, 1 is accepted
1. This depends on the relation between the types and what you would like to show in the UI of the app. Using the SDK should be the usual case, unless, you want the items in a data source instance too and would like to update them from there.
2. This appears to be a JavaScript scope issue. For example, the component you are currently using cannot see the companyListViewModel.
You may try to locate the module and its properties in a similar fashion:
dataSource = app.companyList.companyListViewModel.get(
'dataSource'
);
I hope that this helps.
Regards,
Anton Dobrev
Telerik
Thanks Anton. Regarding point 1, I will continue to use the SDK.
2) I don't think it is a scope issue. The code I posed is part of Comonents\companyListView\index.js inside:
companyListViewModel = kendo.observable({
companyListViewModel is defined but it is the dataSource property that is returning undefined.
Can you confirm:
- The dataSource is initialized and populated when you are in the view that uses it
- Did you try with locating it from another module as specified in my previous reply?
Can you please provide a runnable example and we will take a look into it?
Regards,
Anton Dobrev
Telerik
Hi Anton,
I can confirm that when I am using the CompanyView pages, the dataSource is populated and working as normal. dataSource.data() return an array of objects, one per company document. However when I call it as above, even using the full:
dataSource = app.companyList.companyListViewModel.get(
'dataSource'
);
dataSource is valid but dataSource.data() is [].
I will attempt to create an example, I assume on dojo.telerik.com. I have used these as found in the docs but never created my own. Is this the best option rather than jsbin or jsfiddle.
Any pointers / guides for getting started with created a runnable example?
Thanks,
David
Indeed, it appears that the data source property can now be properly retrieved as a reference. It appears, however, that it was not fetched from the server at the time you are accessing it. Perhaps the view that utilizes the data source initially should be opened prior to interacting with its data source from another view.
I'd suggest that you check this scenario and the read and fetch methods of the Kendo UI data source. Also, check the autoBind configuration of the view that utilizes the data source.
To fully replicate the app behavior, you can create a simple project in the Views service and attach it in this thread, because this will be more illustrative than using the Kendo UI Dojo.
I hope that this helps.
Regards,
Anton Dobrev
Telerik
Hi Anton,
Sorry was trying to attach a ZIP of the app. It is here on GitHub: https://github.com/david-quadpro/dataSourceTest.git
To reproduce the problem: Run the app, which will open on the Person List (it also happens if the initial view is home). Tap on Joe Bloggs. Tap the Employer button. The alert shows that when running detailsShow() of #compontents/companyListView/details.html the companyListViewModel.get('dataSource') is defined but empty.
The workaround: Run the app and go to the Company List from the navigation. Then return to Person list. The Employer button now shows Acme.
I hope this shows what I am trying to achieve, navigating from one content type to another, and also demonstrates the problem.
Thanks in advance,
David
Indeed, the problem is that the dataSource for the Company type is not populated at the time of navigating to the Company Details from the Person details view. It will be fetched only when the company list is requested.
One approach to accomplish your task is to use the getById method of the JS SDK, for example:
if
(!itemModel) {
app.data.dataSourceTest.data(
"Company"
).getById(companyID).then(
function
(data) {
itemModel = data.result;
companyListViewModel.set(
'currentItem'
,
null
);
companyListViewModel.set(
'currentItem'
, itemModel);
},
function
() {
// cannot retrieve the company
});
}
Let me know if this works for you.
On a side note, you can read the Company Name when reading the Person type and show the name of the person's company with the Expand functionality. More info is also available here and here.
Regards,
Anton Dobrev
Telerik
I have finally found a good solution. Posting here for the benefit of others.
My code has evolved a bit but basically the key is that I need to call fetch() in order to ensure that the has the data before calling get().
if
(e.view.params.companyID) {
var
item = e.view.params.companyID;
source.fetch(
function
() {
var
itemModel = source.get(item);
viewModel.set(
'currentItem'
, itemModel);
});
}
else
{
var
item = e.view.params.uid;
var
itemModel = source.getByUid(item);
viewModel.set(
'currentItem'
, itemModel);
}