Is it possible in any way to do the following without have to pass through temporary observables / computed observables? I have common data which is used for lookups to display data:
<span data-bind="text: lookupContactName(31)"></span>
result: function is exectuded, parameter is found, logic ok, and computed full name is returned, but not displayed (probably since no observable)
<span data-bind="text: lookupContactName(contactId)"></span>
result: contactId is not parsed so the correct parameter value is not visible.
I suppose for this to work correctly i would need to create custom bindings?
in general: i started doubting a bit whether or not my approach to load data only once and try to match up id's is a good approach. any views? i'm better of creating joined db tables / views / SP's?
Thanks, J.
here, are the relevant code pieces i'm using... I will learn jsfiddle for future help.
ALL ALERT's are returning the expected values... but still the text data-binding doesn't receive the value
A common data library:
customers.Contact = function () {
var self = this;
id = ko.observable();
title = ko.observable();
givenname = ko.observable();
surname = ko.observable();
fullName = ko.computed(function () {
return title()+". "+givenname()+" "+surname();
});
return {
id: id,
title: title,
givenname: givenname,
surname: surname,
fullName: fullName
};
};
customers.ContactList = function () {
var self = this;
contactList = ko.observableArray([]); //.publishOn("ContactList");
loadContactData = function () {
var self = this;
customers.helperDataService.getContactData(loadContactDataCallBack);
};
loadContactDataCallBack = function (json) {
var self = this;
$.each(json, function (i, p) {
var contact = new customers.Contact().id(p.Id)
.title(p.Title)
.givenname(p.Name)
.surname(p.Surname);
contactList.push(contact);
});
};
lookupContactName = function (id) {
var self = this;
alert("value to be found: "+id);
ko.utils.arrayForEach(contactList(), function (contact) {
alert("SEARCH: contactid: " + contact.id() + " - " + "id: " + id);
if (contact.id() === id) {
alert("FOUND: contactid: " + contact.id() + " - " + "id: " + id);
alert("value:" + contact.fullName());
return contact.fullName();
}
});
};
return {
loadContactData: loadContactData,
lookupContactName: lookupContactName
};
};
Which is called from here... (i changed it to contactId() and this passes the correct value to the function)
<div>Creator: <span data-bind="text: lookupContactName(contactId())"></span></div>
Knockout's declarative binding system provides a concise and powerful way to link data to the UI. It's generally easy and obvious to bind to simple data properties or to use a single binding. For more complex bindings, it helps to better understand the behavior and syntax of Knockout's binding system.
The $data variable is a built-in variable used to refer to the current object being bound. In the example this is the one of the elements in the viewModel.
ko. computed( evaluator [, targetObject, options] ) — This form supports the most common case of creating a computed observable. evaluator — A function that is used to evaluate the computed observable's current value. targetObject — If given, defines the value of this whenever KO invokes your callback functions.
If your <span data-bind="text: lookupContactName(contactId())"></span>
is in a foreach loop then you need to prepend the method with $root or else it will look for "lookupContactName" within the array it is looping trough.
Try:
<div>Creator: <span data-bind="text: $root.lookupContactName(contactId())"></span></div>
Problem is that you lookup function doesn't return a value
ko.utils.arrayForEach(contactList(), function (contact) {
// some checking code
return contact.fullName();
});
your "return" is related to inner function passed to arrayForEach utility method. You need a code like this
var result;
ko.utils.arrayForEach(contactList(), function (contact) {
// some checking code
result = contact.fullName();
});
return result;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With