Joel Kelly
Joel Kelly

Reputation: 217

Change binding value with custom binding in KnockoutJS

I have a custom binding I am using to truncate a description in an observable array. I am just wondering the best way to go about changing the text that is returned to the binding.

    ko.bindingHandlers.summarize = { 
        init: function(element, valueAccessor, allBindingsAccessor, context) {
            var pattern = new RegExp(/^[^.]+/);
            var summarized = pattern.exec(context.description());
            //How do I set the text to the summarized value?
        }
    }

The broad description is used elsewhere on the page. This truncated version is used in the sidebar. Open to suggestions about a better way to go about this but this seemed like the best way to me.

The viewModel is generated from a JSON file via the mapping plugin or I would just add in a truncated version directly in the viewmodel.

Thanks for taking a look at things.

Upvotes: 0

Views: 2076

Answers (2)

Fermentation
Fermentation

Reputation: 31

In your example, you are associating your custom binding with the description in your binding statement data-bind='summarize: description', so you can use the valueAccessor parameter for greater flexibility.

I went a step further and used the ko.unwrap function so your custom binding can handle non-observable values as well:

ko.bindingHandlers.summarize = { 
    init: function(element, valueAccessor, allBindingsAccessor, context) {
    var pattern = new RegExp(/^[^.]+/);
    var summarized = pattern.exec(ko.unwrap( valueAccessor() ) );
    typeof element.innerText == "string" ? element.innerText = summarized
                                         : element.textContent = summarized;
    }
}

Upvotes: 0

Joel Kelly
Joel Kelly

Reputation: 217

Here is what I did. It was simple once I looked at the source of the knockout Library. I would highly recommend digging around in the library code. It is invaluable for learning.

ko.bindingHandlers.summarize = { 
    init: function(element, valueAccessor, allBindingsAccessor, context) {
    var pattern = new RegExp(/^[^.]+/);
    var summarized = pattern.exec(context.description());
    typeof element.innerText == "string" ? element.innerText = summarized
                                         : element.textContent = summarized;
    }
}

To use it in a template you would simply:

<p data-bind='summarize: description'></p>

Where description would be an observable.

Upvotes: 3

Related Questions