I am working on a Master-Detail app. I have a view with list control and I am binding the same with the data from an entityset called "entityset1".
Odata -> data from the entityset1
<serialno>122333</serialno>
I do have another entityset called entityset2 in the same service.
Odata -> data from the entityset2
<hdata>is Active</hdata>
Data from above entityset2 will only be retrieved with the filter (/sap/opu/odata/sap/My_SRV/entityset2?$filter=(serialno=122333)
I am now trying to retrieve the value from the entityset2 and trying to bind it to one attribute in my list. This list is already binded with the entityset1 data.
Myview.xml.
<List id="list" select="_handleSelect">
<ObjectListItem id="MAIN_LIST_ITEM" press="_handleItemPress" title="{Name}">
<attributes>
<ObjectAttribute id="ATTR1" text="{serialno}" />
<ObjectAttribute id="ATTR2" text="{entityset2/hdata}" />
</attributes>
</ObjectListItem>
</List>
Controller.js (binding using the below lines)
this.oList.bindAggregation("items", {
path: '/entityset1',
template: this.oListItem,
filters: this.searchFilters
});
var oserialnum = this.getView().getBindingContext().getObject().serialno;
var oHdata = new sap.ui.model.Filter("serialno", "EQ",oserialnum);
this.searchFilters = new sap.ui.model.Filter([oserialnum],true);
this.oList.bindAggregation("items",{
path : "/entityset2",
filters :this.searchFilters
});
However I am getting an error "Cannot read property 'getObject' of undefined" on this line "this.getView().getBindingContext().getObject().serialno".
Can someone kindly advise how to retrive the data from the entity2 and binding it to the list, ?
You cannot get BindingContext using the view. Read more about binding Context - it's a pointer to an object in Model data.
Also, serialNo(the parameter you are trying to retrieve from the Model is also contextual i.e. it differs with each row item).
One way to do this would be:
onListeItemPress Event of the List
<ObjectListItem ... ... press="onListItemPress" >
In the corresponding Controller
`onListItemPress : function(oEvent){
var oserialnum = Event.getSource().getBindingContext("mainODataModel")..getProperty("serialNo")`
Let me know if this helps.
If I understand you correctly what you need is associations.
They will allow the OData Service to deliver the needed Data from entityset2 directly with the entityset1 through "associating" entityset2 with your serial number.
If you are using a SAP Backend and SEGW this Blog might help you:
https://blogs.sap.com/2014/09/24/lets-code-associationnavigation-and-data-provider-expand-in-odata-service/
I was faced with a similar issue whilst creating a Master-Detail App, but found out from the SAP Forums that this is not possible, which makes sense and ended up creating a separate entityset in the Backend having a link to the other set
Related
I need to merge these two objects:
{ swim_lane_id: $(this).closest('ul').data('lane-id') }
+
$(this).sortable('serialize')
into one object that can be sent as the [DATA] in a $.post:
$.post($(this).data('update-url'), [DATA] );
$.merge only gives swim_lane_id and an id that is part of the update-url data tag but doesn't give the serialized data from the sortable list.
I basically need to be able to pass these through in one post because the update-url data tag routes to a controller action in my Rails application and I need to know which list is being updated for every update action sent to it.
Well that looks simple enough :
$.post $(this).data('update-url'),
swim_lane_id : $(this).closest('ul').data('lane-id')
some_other_name : $(this).sortable('serialize')
You're passing the two properties in one object.
I want to use smart Table like in this sapui5 explored sample but the problem is I have a OData model and the example shows only how we can handle the binding with mock data and also I didn't understand the metadata.xml file. I guess oData model has also its own metadata document. Here my codes in controller :
this.DataPath = "QuarterPerformanceSet";
var oModel = new sap.ui.model.odata.ODataModel(model.Config.getServiceUrl(), true, model.user, password);
oModel.setCountSupported(false);
oSmartTable.setModel(oModel);
oSmartTable.setEntitySet(this.DataPath);
but it doesn't work. I got this error :
Component-changes.json could not be loaded from ./Component-changes.json. Check for 'file not found' or parse errors. Reason: Not Found -
getChanges' failed: -
Simply how can I set entitySet using my odata model?
my view:
<smartTable:SmartTable id="idSmartTable" tableType="Table"
useExportToExcel="true" useVariantManagement="false"
useTablePersonalisation="true" header="Line Items" showRowCount="true"
persistencyKey="SmartTableAnalytical_Explored" enableAutoBinding="true"/>
Thank you in advance if someone can help.
UPDATE 2 : I rebind table according to this discussion
this.DataPath = "QuarterPerformanceSet";
var oModel = new sap.ui.model.odata.ODataModel(model.Config.getServiceUrl(), true, model.user, password);
oModel.setCountSupported(false);
var oSmartTable = this.getView().byId("idSmartTable");
oSmartTable.setModel(oModel);
oSmartTable.setEntitySet(this.DataPath);
oSmartTable.rebindTable();
sad to say but still I got same error.
You need to pass the name of entity set, not the model instance. If you have for example an entity set Customers defined you just do:
oSmartTable.setEntitySet("Customers");
or add the attribute entitySet to your table declaration.
<smartTable:SmartTable id="idSmartTable" entitySet="ENTITY_SET" .../>
I'm a newbie to Knockout.js. I implemented the Knockout.js by loading data from ajax source and use foreach loop to create a table of the data. The tutorial i followed is here
http://www.dotnetcurry.com/ShowArticle.aspx?ID=933
My issue here is, due to the nature of my application, I find that the first load is better served from the server side using a grid component and I only want Knockout.js to take care of "Add" row, "Update" a row and "delete" a row.
My question is,
1) how do I replace the "first" load and populate the lookupCollection :ko.observableArray() in the article with the default data in the html table?
2) Related to #1. If the first load, the table layout with data is constructed from the server side, then how do I bind "foreach" to the grid so "add" can be performed on lookupCollection?
Thanks and again, I'm a newbie, I must be missing some key concepts here.
One way would be to pass your initial data into your view model. Since you are using asp.net it would look something like this:
//Dump raw data into javascript variable
var data = #Html.Raw(ViewBag.Data);
function ViewModel(data) {
var self = this;
//Unpack raw data
self.lookupCollection = ko.observableArray(data.lookupCollection);
}
//initialize view model
var viewModel = new ViewModel(data);
ko.applyBindings(viewModel);
I'm using AngularJS to build an application that allows users to build reports and then submit them. The title and the time of creation are automatically generated (based on user input), and the report summary is added into a list of all of the reports the user has made.
The table will be eventually populated from a server-side JSON string (and new entries will be added to the server from the local session), but for my local testing, I need a way to add to the table during a local client-side session.
A user will go to a separate page where they can create a report: once they click "Run Report," the report summary should be added to the table, where the name of the report and the date it was created are automatically populated from the user's input. The report-creating interface is on a different page and consequentially a different controller scope from the "main" page where the list of report summaries resides.
Now, here's my question: what is the best, most Angular-tastic way to submit a report summary to the table (a.k.a. a local model) from a different controller $scope?
My code looks like this (keep in mind it is probably dreadful, and I'm planning to refactor it!):
controllers.js:
var MainCtrl = function($scope) {
$scope.reports = [
{name:'Trx Summary', date:'Mar 20, 2013 # 12:30PM'},
{name:'Trx Summary', date:'Mar 20, 2013 # 12:30PM'}
];
};
_dat_partial_view.html:
<div ng-controller="MainCtrl" class="row-fluid">
<table class="table table-striped">
...
<tr ng-repeat="report in reports">
<td>
<p>{{report.name}} <span class="label label">Generating</span></p>
</td>
<td>
<dl class="no-margin">
<dt>Date Range</dt>
<dd>Mar 3, 2013 - Mar 13, 2013</dd>
<dt>Generated</dt>
<dd>{{report.date}}</dd>
</dl>
</td>
...
</tr>
This successfully creates some dummy content that populates the table with two entries.
What do I need to do to create such a dynamic list-adder? I'm pretty sure I need to push elements into the array, but I have no idea how to do so outside of the current controller $scope. I tried placing the array's code outside of the controller $scope:
controllers.js:
reports = [
{name:'Trx Summary', date:'Mar 20, 2013 # 12:30PM'},
{name:'Trx Summary', date:'Mar 20, 2013 # 12:30PM'}
];
var MainCtrl = function($scope) {};
This simply removed the two dummy entries from the table, so that didn't work.
Any ideas?
Question 2
Another question: What is the best way to create the dynamic list of content that populates the table? The app will create the report, and store it locally. It will then try to push the new report to the server, which will generate the report and theoretically send back a result that concatenates to the JSON string. In other words, the report stays local until it is successfully sent to and generated by the server. The user cannot read the report until it is generated, but the report will also remain saved locally if the server cannot, for some reason, accept the request to generate the new report.
This said, I've seen examples that suggest using a service or factory. Is this the wisest thing to do? Is this better than a simple array like what I've got set up now?
You should be using a service here, I think the example you referenced is the correct approach
You can pass objects into a different scope by using broadcast.
controllerOne
$rootScope.$broadcast('ReportSubmit', $scope.reportObject);
data can be your object from your controller.
Then it listens for the broadcast in the other controller where you can define your data and manipulate it and have access to it..
controllerTwo
$scope.$on('ReportSubmit', function(event, data) {
$scope.reportObject = data;
};
For the second question, when you create new report, if you have the model bindings on the front-end you can do it like this.
This function you'd bind to ng-click on the create action passing in your object from the form fields.
$scope.createNewReport = function(object) {
// Assign object to var
var newReport = object;
//Add new object to data from in memory object.
$scope.reportList.push(newReport);
};
You can pass it back to the controller or server by using ajax to pass the reportList object
Found a fiddle that may potentially help you out. http://jsfiddle.net/yh3Ds/24/
I'm having massive problems with databinding to a ListView in a Windows 8 app using Javascript.
Inside the "activated" event on default.js I have written some code to get some data from a web service and push it into an array. This bit works OK and the array is populated.
The problem I have is that the app won't recognise the data. I have this code in a page called inspections.html:
data-win-options="{itemTemplate: select('#imageTextListCollectionTemplate'),
itemDataSource: dataList.dataSource,
layout: {type: WinJS.UI.ListLayout}}
and then in the "activated" event I declare:
var dataList = new Array();
and push the data from the web service into this array. But at runtime I get an error that says something along the lines of "can't find dataSource on undefined dataList".
I've done some of the examples on the MS website and in one of them it creates a dummy dataset and references it from a namespace. I kinda think that what I'm missing here is a namespace too but I don't know what the namespace for default.js is. Or maybe I'm wrong and it's something totally different.
Please help - this is so fundamental (and should be easy) but I can't get my head around it.
Do you want to create datalist in HTML or javascript?
It seems you want to create it from JavaScript. Assuming that you have already pushed your data into array from your webservice, you only need to call:
var dataList = new WinJS.Binding.List(array);
now accessing dataList.dataSource is perfectly valid.
Also, to create the datalist you don't always need an array. You could probably start with an empty list and then keep inserting data directly into the data list from web services, like:
var dataList = new WinJS.Binding.List([]);
dataList.push(value1);
dataList.push(value2);
...
Hope it helps. Let me know if you have any more questions.
If you are getting troubled by assigning datasource in HTML side
Prefer js side like
var list = new WinJS.Binding.List(array here);
listView.itemDataSource = list.dataSource;
by using this you can easily go through the data which you are binding to ListView.