Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Html element from ko.computed

Is it possible to access bound element from ko.computed function?

Something like this pseudo code (simplified for clarity):

<h1 id="id1" data-bind="visible: myComputed">
<h1 id="id2" data-bind="visible: myComputed">
<h1 id="id3" data-bind="visible: myComputed">

...

self.myComputed = ko.computed(function(){
        return <BOUND_ELEMNT>.id == 'id2';
    });

Resulting in only the second element showing.

Note: I'm aware I can have a separate computed for every element, but it is not possible in my case.

EDIT:

Ok - I'll give a more accurate example. The following is similar to what I have:

<section id="id1" data-bind="visible: myComputed1">A lot of code</section>
<section id="id2" data-bind="visible: myComputed2">different lots of code</section>
<section id="id3" data-bind="visible: myComputed3">Other lots of code</section>

...

// This field's value changes over time (between 'id1', 'id2' and 'id3').
// Some complex logic changes this field,
// and as a result only one h1 is showing at a time.
self.myField = ko.observable();
self.myComputed1 = ko.computed(function(){
        return self.myField() == 'id1';
    });
self.myComputed2 = ko.computed(function(){
        return self.myField() == 'id2';
    });
self.myComputed3 = ko.computed(function(){
        return self.myField() == 'id3';
    });

This is an ugly violation of the DRY principle, and I would like to find a way to refactor it. The pseudo code above may solve it, but I'm open for suggestions...

like image 487
seldary Avatar asked Sep 15 '25 10:09

seldary


1 Answers

You've created a short, simplified example, which is normally great. However, it feels like you've introduced an XY-problem instead. As such, this answer may or may not be helpful.

You're trying to introduce a dependency on the View in your ViewModel. It should be the other way around! Something like this would make more sense:

<h1 data-bind="visible: myComputed, attr { id: myId }"></h1>

Note the use of the attr binding to set the id. Your ViewModel should be constructed accordingly:

var activeHeaderId = 'id2';

var viewModel = function(id) {
    var self = this;

    self.myId = ko.observable(id);

    self.myComputed = ko.computed(function() {
        return self.myId() === activeHeaderId;
    });
}
like image 179
Jeroen Avatar answered Sep 17 '25 00:09

Jeroen