0

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

2 Answers 2

1

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
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, sure this is it. declared var self = this; and its work :)
0

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.

1 Comment

Yeah, sure this is it. declared var self = this; and its work :)

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.