I'm trying to show some data retrieved by Odata Model on a XML View.
In Component.js, I create a model with service Url and it works as usual.
var oDataModel = new sap.ui.model.odata.v2.ODataModel("http://server:port/sap/opu/odata/SAP/ZWYMB_SRV", {
user:"abapleader",
password: "TH123456789a#",
headers: {
"sap-client": 300
},
useBatch:false
});
this.setModel(oDataModel, "oDataModel");
So far, I've managed to get data to master using model.read() function.
Now I need to show the detail view. My code for onInit event is below:
this.router.getRoute("zwm01detail").attachPatternMatched(this._onObjectMatched.bind(this));
},
_onObjectMatched: function(oEvent) {
var that = this;
var MaWorkDoc = oEvent.getParameter("arguments").MaWorkDoc;
this.getModel("oDataModel").metadataLoaded().then(function() {
var sPath = that.getModel("oDataModel").createKey("/WorkDocList", {
MaWorkDoc: MaWorkDoc,
Pernr: "0001"
});
console.log(sPath);
that.getView().bindElement({
path:sPath
});
});
The sPath as I printed out using console.log(sPath) : /WorkDocList(MaWorkDoc='1110000001',Pernr='0001'), which I think, is correct. I also implemented and tested the back-end using this path and basically things are fine. But I don't know why I cannot show data on the view.
Detail.view.xml:
<Text text="{/MaWorkDoc}" maxLines="0"/>
Any suggestions, please?
Because you have given your model a name you will need to use that name in the binding. i.e. <Text text="{oDataModel>/MaWorkDoc}" maxLines="0"/>
So I've been working around with the docs and figure out there is model parameter which helps.
To be more specific, I add declare model in view.bindElement as below:
that.getView().bindElement({
path:sPath,
//** oDataModel = name of the model
model: "oDataModel"
});
If there is any better solution, I'd very glad to know it. Thank you.!
I do not think the detail binding code should be inside the .metadataLoaded handler. Rather it should be directly inside _onObjectMatched.
I mean like this.
_onObjectMatched: function(oEvent) {
var that = this;
var MaWorkDoc = oEvent.getParameter("arguments").MaWorkDoc;
var sPath = that.getModel("oDataModel").createKey("/WorkDocList", {
MaWorkDoc: MaWorkDoc,
Pernr: "0001"
});
console.log(sPath);
that.getView().bindElement({
path:sPath
});
}
Related
I have a oData model with entities : Order, OrderInformation. There is 1 : 1 an association between Order and OrderInformation.
Now in the view, based on a value in OrderInformation, I should hide / display a button.
In the controller, following logic to get the value of OrderInformation->appUrl does not work but I can read the property of entity 'Order'.
Init: function(){
// Not working
var prop = this.getView().getModel().getProperty("/OrderInformations('"+ this._orderId + "')/appUrl");
// Working
var prop = this.getView().getModel().getProperty("/Orders('"+ this._orderId + "')/orderType");
}
In transaction /IWFND/GW_CLIENT, following query gives me correct value
/sap/opu/odata/sap/<<ServiceURL>>/OrderInformations('132123')/appUrl
I also tried with the attachRequestCompleted but still no success.
Init:function(){
var oModel = this.getView().getModel();
oModel.attachRequestCompleted(function(oEvent){
var myval = model.getProperty("/OrderInformations('"+ this._orderId + "')/appUrl");
});
}
Can someone provide any idea what can be going wrong ?
BR
Nilesh
You can use the oModel.read function to trigger a request to the backend, within the success handler you read the result of the response and process the received data
var test = oModel.read("OrderInformations('" + this._orderId + "')", {
success: function(oData, response) {
var appUrl = oData.result.appUrl; //response.data.appUrl also works
// do something
},
error: function (oError) {
// Error handling on failed response
}
});
API reference: https://openui5beta.hana.ondemand.com/#docs/api/symbols/sap.ui.model.odata.ODataModel.html#read
I don't understand this line you wrote:
In the controller, following logic to get the value of
OrderInformation->appUrl does not work but I can read the property of
entity 'Order'.
Order is another Entity with a property and the addressing for this works like described above?
Did you init your model like this:
/sap/opu/odata/sap/<<ServiceURL>>/Order? Is OrderInformation a related entity of Order? If yes extend the read with the Navigation property of the odata service which defines the relationship between the two Entities
I hope this answers you question, if anything left, let me know
Best regards
I have 2 lists in a view. What I want to do is that pick elements from list1 and update list2 with selected elements everytime I pick one. I tried to use PartialView (I don't know if it's correct approach or not) but I failed. I have a function in controller that fills a list by selected items. What needs to be done is updating the view dynamically. Can you suggest me a roadmap for this?
Update
I forgot to say that I have done this with javascript. But I feel like it's the long way when it comes to some validations (checking duplications etc.)
$(document).ready(function (){
$("#allPlayersList a").on("click", function () {
var options = $(this).clone();
$("#thisWeekList").append(options);
});
});
Just create an html list. See if this link helps. https://codepen.io/alexander-holman/pen/QNQrvz. You can also populate the values from database
Then you can get the selected element by javascript like this
var input = document.getElementById('Something').value;
Update after edited question
You can try something like
var listSelection = document.getElementById('Something').value;
Now you can create an api in the backend which accepts this value and returns a list based on it. Call that Api like this
&.ajax({
url: //url of api
data: {exactNameOfApiParameter : listSelection },
success: function(data){
for (i = 0; i < data.length; i++) {
$('<li>', { text: data[i] }).appendTo($('#list2'));
}
}
})
Make sure that id of second list is list2.
My collection and model like this:
detail_userid = 0;
detail_contactid = 0;
var ContactDetail = Backbone.Model.extend({
urlRoot: URL_CONTACTS1+detail_userid+"/"+detail_contactid
});
var ContactDetailCollection = Backbone.Collection.extend({
model: ContactDetail,
url: URL_CONTACTS1+detail_userid+"/"+detail_contactid
})
The entrance is:
ContactDetailManagePageModel.prototype.init = function(m,n){
detail_userid = m;
detail_contactid = n;
var myContactDetails = new ContactDetailCollection();
var contactDetailListView = new ContactDetailListView({
collection: myContactDetails
});
myContactDetails.fetch({reset:true});
}
But when it runs,the url is :http://localhost:8080/ws/users/contacts/0/0,it means that the assignment to detail_userid and detail_contactid is unsuccessful,I don't know why.
Hope for your help.Thanks.
I think you are statically definining the urlRoot and url properties before you are running the init of the PageModel (not quite sure where you are getting m and n from though...)
Both url and urlRoot can be a function, so you can pass in options during instantiation and have them dynamically set on the model.
Simple example covering defining the collection and then creating one
var ContactDetailCollection = Backbone.Collection.extend({
model: ContactDetail,
url: function(){
return URL_CONTACTS1 + this.options.detail_userid + "/" + this.options.detail_contactid;
}
});
var myContactDetails = new ContactDetailCollection({
detail_userid: foo,
detail_contactid: bar
});
As I mentioned, I'm not sure what your init function is doing, I'm guessing it's something custom from your app that I don't need to worry about.
I'm fairly sure the main thing to take away is to set url and urlRoot dynamically
I would fulfill the accepted answer with few remarks.
First parameter when initializing Backbone.Collection is array of models, then options. To create an empty collection with options you should do next
var c = new Backbone.Collection(null, {opt1: val1, opt2: val2});
Actually, you can't access this.options in url function, bec. there are no options like in a model. What you can do, is assign required properties from options upon initialization.
initialize: function (models, options) {
// `parseInt()` is used for consistency that `id` is numeric, just to be sure
this.detail_userid = parseInt(options.detail_userid);
this.detail_contactid = parseInt(options.detail_contactid);
}
Later you can access them like this:
url: function() {
return URL_CONTACTS1 + this.detail_userid + "/" + this.detail_contactid;
}
I wanted to use the HATEOAS href from one model to fetch data of another model. It worked to simply set the url on the newly created collection instead of defining it right away in the constructor.
var DailyMeasuresCollection = Backbone.Collection.extend({
//url : set dynamically with collection.url = url
model : DailyMeasuresModel,
parse : function(data) {
return data._embedded.dailyMeasures;
}
});
var DailyMeasuresTopicListItemView = Backbone.View.extend({
//...
events : {
'click .select-topic' : 'onClick'
},
onClick : function() {
var topicMeasures = new DailyMeasuresCollection()
topicMeasures.url = this.model.attributes._links.measures.href // <- here assign
var topicMeasuresView = new DailyMeasuresListView({
collection : topicMeasures
});
topicMeasures.fetch()
}
});
I have a textbox for username in a form, when user enter the username, i need to check if that username is already in data base. I'm thinking to catch the blur event of the text box & to write a javascript function to query & check in database. I'm trying some thing like this:
#html.textboxfor(x=>x.UserName, new{#id="UserName"})
<script type="text/javascript">
$(document).ready(function(){$('#UserName').blur("then some code here");})
</script>
Now I need to know if I'm following the right way? If so then please let me know how can I call a action method which will interact with the database within the blur function or whats the right way? Thanks in advance.
Yes, that looks right. You can use a JQuery Ajax call, along with the Url.Action helper method.
$(document).ready(function(){
$('#UserName').blur(function() {
var name = this.value;
$.get(#Url.Action("VerifyUsername") + "?name=" + value, function(result) {
if (result.ok == false) {
$("#message").text("Username '" + name + "' is already taken, please try another");
}
});
});
});
This will call an action VerifyUsername in the current controller. It assumes that the action returns JSON like {ok:true} to verify the name:
public ActionResult VerifyUsername(string name)
{
bool isOk;
// check the database
return new JsonResult() {
Data = new { ok: isOk },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
you can use remote validation in MVC3
http://msdn.microsoft.com/en-us/library/gg508808(v=vs.98).aspx
I want to build a client for my REST-Service using Knockout.js.
I have a lot of Repositorys i want to access through different urls - so i came up with this solution using the Revealing-Prototype-Pattern.
My problem: I can not find out how to map the ItemsProperty with my "data" i receive from my service.
var Repository = function (url) {
this.Url = url;
this.Items = ko.observableArray([]);
this.PendingItems = ko.observableArray([]);
};
Repository.prototype = function () {
var
getAllItems = function () {
var self = this;
$.getJSON(self.Url, function (data) {
// data=[{"Id":1,"Name":"Thomas","LastName":"Deutsch"},{"Id":2,"Name":"Julia","LastName":"Baumeistör"}]
ko.mapping.fromJS(data, self.Items);
});
},
...
// i call it like this:
customerRepository = new Repository('http://localhost:9200/Customer');
customerRepository.getAllItems();
I think the problem is in this: ko.mapping.fromJS(data, self.Items); but i can not find the right way to do it.
Question: what am i doing wrong? i have found an example - and they are doing the same i think: http://jsfiddle.net/jearles/CGh9b/
I believe that the two argument version of fromJS is only used for objects that were previously mapped, i.e they had an implicit empty mapping options object. Since your mapping is the first time it has been run, it needs to provider that empty options object like so.
ko.mapping.fromJS(data, {}, self.Items);
http://jsfiddle.net/madcapnmckay/j7Qxh/1/
Hope this helps.