Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

I have a brand list and brands contains car list. Declared simple view model in knockout on http://jsfiddle.net/PZqEk/1/ . this.cars is undefined in removeCar function when clicking remove button. How to delete clicked car with best practice?

Html:

<h1 data-bind="text:title"></h1>
<table>
    <tbody data-bind="foreach: brands">
        <tr>
            <td>
                <span data-bind="text: nameOfBrand"></span>
                <ul data-bind="foreach: cars">
                    <li>
                        <span data-bind="text: nameOfCar"></span>
                        (<span data-bind="text: yearOfCar"></span>)
                        <input data-bind="click: $root.removeCar" type="button" value="remove"/>
                    </li>
                </ul>
            </td>
        </tr>
    </tbody>
</table>

Javascript:

function RootModel()
{
    this.title = ko.observable("Dummy Title");
    this.brands = ko.observableArray();

    var b1 = new brandModel("Audi");
    b1.cars.push(new carModel("A3", 2005));
    b1.cars.push(new carModel("A6", 2005));

    var b2 = new brandModel("Volkswagen");
    b2.cars.push(new carModel("Golf", 2010));
    b2.cars.push(new carModel("Passat", 2008));
    b2.cars.push(new carModel("Polo", 2012));

    this.brands.push(b1);
    this.brands.push(b2);
}

function brandModel(name)
{
    this.nameOfBrand = ko.observable(name);
    this.cars = ko.observableArray();

    this.removeCar = function(car){
        this.cars.remove(car); // this.cars = undefined;
    }
}

function carModel(name, year){
    this.nameOfCar = ko.observable(name);
    this.yearOfCar = ko.observable(year);
}

ko.applyBindings(new RootModel());

Thanks

share|improve this question
up vote 1 down vote accepted

The problem is that you're accessing this from a function that is not called on the instance. You'll need an alias.

function brandModel(name) {
    var self = this; // alias
    self.nameOfBrand = ko.observable(name);
    self.cars = ko.observableArray();

    self.removeCar = function(car) {
        self.cars.remove(car); // access through the alias instead
    }
}
share|improve this answer
1  
Yeah, sure this is it. declared var self = this; and its work :) – Omer Faruk Zorlu Mar 5 '13 at 19:49

Jeff is correct in that you should alias this (commonly by declaring self = this; at the top of a model), and I would recommend doing that for every Knockout application you make.

However, I did not notice that you were using this at first, and immediately tried this code:

<input data-bind="click: function(data, event) { $parent.removeCar(data); }" type="button" value="remove"/>

and as the only change to your fiddle, that worked.

share|improve this answer
    
Yeah, sure this is it. declared var self = this; and its work :) – Omer Faruk Zorlu Mar 5 '13 at 19:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.