Obtaining data-bind attributes after rendering for acceptance test lookups

158 views
Skip to first unread message

hlasc...@gmail.com

unread,
Jul 26, 2012, 1:32:34 PM7/26/12
to knock...@googlegroups.com
We love using knockout, but need a quick way to "find" elements onscreen using capybara.

Knockout cleans up after itself so that the final rendered nodes have no data-bind attribute.
Is there some way we can get it to (maybe only in test mode config) set attributes on the nodes based on parsed bindings?

There are a million ways to skin this cat, but ultimately, given a page of several input boxes, it would be very handy
to be able to lookup fields in capybara using data we have already supplied in the data-bind attribute.

eg:

<div data-bind="bindme: foo, options: bar">

could render to

<div data-bind-bindme="foo" data-bind-options="bar">

For now I shimmed the value binding to do something similar, but it is hacky, and doesn't cover selects, checked, and any future bindings.

NB! It is no good to me to add a real JS hash to the element nodes. Capybara works on a very "browser" level of interaction, so a real attribute is the best
way forward.

Cheers!

hlasc...@gmail.com

unread,
Jul 26, 2012, 1:52:16 PM7/26/12
to knock...@googlegroups.com, hlasc...@gmail.com
Here is the method we use right now. It sets the "name" property based on a "property_name" attribute we inject in our model by visiting it with ko.mapping.


    for (var key in ko.bindingHandlers) {
        if (ko.bindingHandlers.hasOwnProperty(key)) {
            var original_init = ko.bindingHandlers[key].init;
            ko.bindingHandlers[key].init = function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                var v = valueAccessor();
                if (ko.isObservable(v) && v.property_name){
                    $(element).attr('name', v.property_name);
                    original_init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
                }
            };
        }
    }

rpn

unread,
Jul 26, 2012, 10:06:02 PM7/26/12
to knock...@googlegroups.com, hlasc...@gmail.com
Are you using jQuery Templates or possibly another template engine?  Otherwise, the "data-bind" attributes would be there in the markup.

hlasc...@gmail.com

unread,
Jul 27, 2012, 4:59:57 AM7/27/12
to knock...@googlegroups.com, hlasc...@gmail.com
Thanks, yes you're right, we are... Still time to switch before we go live. Is Knockout data-bind still the best bet, or is JSRender the way forward?

NB, Even if the unparsed attributes are still there, that's an improvement. For Christmas, I would like the HTML nodes with string attributes already populated in a manner of my choosing. So, in short, where is the killer line in Knockout that says "taking this attribute string data-bind="value: foo", get the foo object." 

*Just before* that (or after, I'm not fussy), I would like a callback so I can work on the data-bind string with access to the node.

Anyway, thanks for your help. I'll report back!

rpn

unread,
Jul 27, 2012, 8:59:27 AM7/27/12
to knock...@googlegroups.com, hlasc...@gmail.com
Sounds like you might be interested in custom binding providers:  http://www.knockmeout.net/2011/09/ko-13-preview-part-2-custom-binding.html.  This would give you a chance to control how the bindings are specified/parsed.

Michael Best

unread,
Jul 27, 2012, 5:07:35 PM7/27/12
to knock...@googlegroups.com, hlasc...@gmail.com
This also requires that you use Knockout's native template engine because jQuery templates don't use the binding provider.

-- Michael
Reply all
Reply to author
Forward
0 new messages