knockout.js - $component incorrect within foreach binding inside a KO component -
js fiddle showing issue: http://jsfiddle.net/davetropeano/58vm9r6g/7/
i have custom component renders observable array. list elements readonly , trying support letting user delete element.
here's template:
<template id="kv-list"> <input type="text" placeholder="key" data-bind="textinput: k"> <input type="text" placeholder="value" data-bind="textinput: v"> <button data-bind="click: add">add</button><br> <table> <thead> <tr> <th data-bind="text: keyheading"></th> <th data-bind="text: valueheading"></th> <th></th> </tr> </thead> <tbody data-bind="foreach: items"> <tr> <td data-bind="text: k"></td> <td data-bind="text: v"></td> <td><a href="#" data-bind="click: $component.delete">delete</a></td> </tr> </tbody> </table>
and viewmodel , registration code:
function kv(k, v) { self = this; self.k = k; self.v = v; } function kvpairlist(params) { this.items = params.items; this.keyheading = params.keyheading || 'key'; this.valueheading = params.valueheading || 'value'; this.k = ko.observable(); this.v = ko.observable(); } kvpairlist.prototype.add = function () { this.items.push(new kv(this.k(), this.v())); }; kvpairlist.prototype.delete = function (item) { this.items.remove(item); }; function vm(params) { this.title = params && params.heading ? params.heading : 'ko component example'; this.variants = ko.observablearray(); } ko.components.register('kvlist', { viewmodel: kvpairlist, template: { element: 'kv-list' } }); ko.components.register('page-main', { viewmodel: vm, template: { element: 'wrapper' } }); ko.applybindings();
adding observable array works fine. if click delete on 1 of rows ko throughs error:
uncaught typeerror: cannot read property 'remove' of undefined
it looks happening $component not context of component's viewmodel -- item inside foreach binding. tried $parent same effect.
is there way access component's viewmodel inside foreach loop?
(js fiddle showing issue: http://jsfiddle.net/davetropeano/58vm9r6g/7/)
for reason 'this' inside remove method not refferring kvpairlist.
this why proffer use scoped variable refer instance , prevent closure issues:
try this:
function kvpairlist(params) { var self = this; self.add = function(){ self.items.push(new kv(this.k(), this.v())); }; self.delete = function(item){ self.items.remove(item); } self.items = params.items; self.keyheading = params.keyheading || 'key'; self.valueheading = params.valueheading || 'value'; self.k = ko.observable(); self.v = ko.observable(); }
and view model code becomes more self-contained well.
fiddle here:
Comments
Post a Comment