Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KO data-binding "text:" to a function with a parameter

Tags:

knockout.js

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>
like image 536
jcuypers Avatar asked Apr 18 '13 13:04

jcuypers


People also ask

What are Knockout bindings?

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.

What is $data in Knockout?

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.

What is Ko computed in Knockout js?

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.


2 Answers

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>
like image 166
PercivalMcGullicuddy Avatar answered Oct 20 '22 15:10

PercivalMcGullicuddy


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;
like image 41
Sergey Savchuk Avatar answered Oct 20 '22 16:10

Sergey Savchuk