1

In Durandal, I'm working on a page that lists a number of doctors. Each row has a delete button. Here's my View Model:

var Doctor = function() {};

Doctor.Model = function(data) {
  this.id = data.id;
  this.name = ko.observable(data.name);
};

Doctor.prototype.activate = function() {
  this.doctorArr = ko.observableArray();

  // Start Doctor List
  this.load();
};

Doctor.prototype.load = function() {
  // load list into this.doctorArr()
}

Doctor.prototype.remove = function() {
  console.log(this);
};

And here's my View:

<button data-bind="click: remove">Remove Function</button>

<ul data-bind="foreach: { data: doctorArr }">
  <li>
    <span data-bind="text: name"></span> - <a data-bind="click: $parent.remove">Delete...</a>
  </li>
</ul>

Clicking on the <button> will return:

Doctor {doctorArr: function, activate: function…}

But clicking on the link inside the foreach function will return the model:

Doctor.Model {id: "104", name: function}

The problem is that I can't figure out how to access doctorArr from inside the remove function when 'this' returns the Model. I need it to remove the item.

3 Answers 3

1

You need to use the method bind to change the 'meaning' of this (the scope) inside the function you are calling. You have some options:

Add the bind to call the ViewModel within the desired scope:

<li>
    <span data-bind="text: name"></span> - <a data-bind="click: $parent.remove.bind($parent)">Delete...</a>
</li>

If you want to remove it without a method in the ViewModel. This will magically remove the item from the array:

<li>
    <span data-bind="text: name"></span> - <a data-bind="click: $parent.doctorArr.remove.bind($parent.doctorArr)">Delete...</a>
</li>
Sign up to request clarification or add additional context in comments.

Comments

0

The problem is that inside your view model you aren't assigning what 'this' is, so each time you are calling remove it is passing in a different context.

var Doctor = function() {};

Doctor.Model = function(data) {
  var self = this;
  this.id = data.id;
  this.name = ko.observable(data.name);
};

Doctor.prototype.activate = function() {
  var self = this;
  this.doctorArr = ko.observableArray();

  // Start Doctor List
  this.load();
};

Doctor.prototype.load = function() {
  var self = this;
  // load list into this.doctorArr()
}

Doctor.prototype.remove = function() {
  var self = this;
  console.log(this);
};

1 Comment

Even if I assign this to self, it will still return the Model.
0

The first argument knockout passes to your event bindings is the root model:

Doctor.prototype.remove = function(model) {
  console.log(model.doctorArr);
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.