1

I am passing $index and $data to the change_model function. The function is expecting 2 parameters in the following order: (index, data).

From the viewModel I am passing click: $root.change_model.bind($data, $index()). Within the function index prints $data, and data prints index: values are reversed.

self.change_model = function(index, data) {
  self.patternSelectedIndex(index);
  selected_door = data.file;
  create_door();
};
<div data-bind="foreach: x.patterns">
    <div class="thumbnail" data-bind="css: { selected: $index() === $root.patternSelectedIndex() }">
      <img class='img model' style='width:164px;height:90px;padding:5px' data-bind="attr:{src:'images/models/' + $data.file + '.png'}, click: $root.change_model.bind($data, $index())" />
      <div class="caption">
        <span data-bind="text: $data.name"></span>
      </div>
    </div>
</div>
Jeroen
  • 60,696
  • 40
  • 206
  • 339
  • 1
    It may help if you include a *wee* bit more code to make a full repro, which makes it easier for others to help you. Something like [this jsfiddle](http://jsfiddle.net/cz2jw41s/1/). – Jeroen Jun 18 '15 at 22:01
  • possible duplicate of [Use of the JavaScript 'bind' method](http://stackoverflow.com/questions/2236747/use-of-the-javascript-bind-method) – CrimsonChris Jun 19 '15 at 04:45

1 Answers1

2

The first argument of bind will become this inside your function, because Knockout is merely using the regular bind function.

You can either pass $data or $root as the first (thisArg) argument, or pass null or undefined, as you don't really need it since you seem to use the self = this idiom.

For example:

var ViewModel = function () {
    var self = this;

    self.change_model = function (index, data) {
        console.log(this);
        console.log(index);
        console.log(data);
        // Actual code here
    };

    self.x = { patterns: [{ file: 'some-file', name: 'some-name' }] };
};

ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div data-bind="foreach: x.patterns">
    <button data-bind="click: $root.change_model.bind($data, $index(), $data)">Click me!</button>
    <span data-bind="text: $data.name"></span>
</div>
Jeroen
  • 60,696
  • 40
  • 206
  • 339
  • 1
    You never explained why the arguments seemed reversed. The click binding automatically passes the context as an argument to the bound function. This means that the third argument of the bind in your example isn't required. – CrimsonChris Jun 20 '15 at 04:06