1

我正在学习 KO 并尝试创建一个简单的列表项添加/删除。但我有以下问题。

Q1:如果您点击添加而不输入名称,您刚刚添加的项目将具有result名称。为什么以及如何在允许空作为有效输入的同时防止它?

Q2:我想使用<pre>标签显示当前视图模型的 JSON,但它没有显示任何内容。但是按钮显示了一些东西。我想出了这个。我需要使用ko.toJSON($data, null, 4).

Q3:和Q2有关,按钮显示了一些东西,但是显示的东西看起来很奇怪。输入几个项目后,然后单击debug按钮。您将看到视图模型中的所有项目都被您更改的最后一项替换。

这是小提琴

CSS:

input[type=text], select {
    width:100px;
}

JS:

function foodie() {
    this.name;
    this.food;
}

function foodieApp() {
    var self = this;
    self.foodies = ko.observableArray();
    self.foodieToAdd = ko.observable(new foodie());

    self.addFoodie = function () {
        this.foodies.push(this.foodieToAdd());
    };

    self.delFoodie = function (foodieToDel) {
        self.foodies.remove(foodieToDel);
    };

    self.debug = function () {
        alert(ko.toJSON(self, null, 4));
    };
}

var app = new foodieApp();
ko.applyBindings(app);

HTML:

<table>
    <thead>
        <tr>
            <td>Foodie's Name
                <br/>
                <input type=text data-bind='value: foodieToAdd().name' />
            </td>
            <td>Foodie's Food
                <br/>
                <select data-bind='value: foodieToAdd().food'>
                    <option value=apple>Apple</option>
                    <option value=banana>Banana</option>
                    <option value=cherry>Cherry</option>
                </select>
            </td>
            <td>
                <input type=button value=Add data-bind='click: addFoodie' />
            </td>
        </tr>
    </thead>
    <tbody data-bind='foreach: foodies'>
        <tr>
            <td>
                <input type=text data-bind='value: name' />
            </td>
            <td>
                <select data-bind='value: food'>
                    <option value=apple data-bind>Apple</option>
                    <option value=banana>Banana</option>
                    <option value=cherry>Cherry</option>
                </select>
            </td>
            <td>
                <input type=button value=del data-bind='click: $parent.delFoodie' />
            </td>
        </tr>
    </tbody>
</table>
<input type=button value=debug data-bind='click: debug' />
<!-- why the following <pre> tag is empty? -->
<pre data-bind='text: ko.toJSON(app, null, 4)'></pre>
4

1 回答 1

2

这是一个更新的小提琴:http: //jsfiddle.net/jearles/TgD6a/3/

--

  • Q1:你没有初始化你的foodie对象
  • Q2:app不是您的 ViewModel 的一部分 - 它是 ViewModel。用于$root访问顶级 ViewModel
  • Q3:这与你定义的方式有关foodieToAdd。基本上,您只创建一个实例,因此 Knockout 会一遍又一遍地添加相同的对象。因为您没有可观察的属性,所以敲除没有更新 UI。

在我的小提琴中,我改变了foodieToAdd定义方式。它现在只是一个标准对象,具有两个可观察的属性。当您单击add它时,它会克隆foodieToAdd以在 observableArray 中创建一个新条目。

编辑:请参阅下面的评论,了解为什么淘汰赛正在兴起result

--

function foodie(foodie) {
    this.name = ko.observable(foodie ? foodie.name() : '');
    this.food = ko.observable(foodie ? foodie.food() : '');
}

function foodieApp() {
    var self = this;
    self.foodies = ko.observableArray();
    self.foodieToAdd = new foodie();

    self.addFoodie = function () {
        this.foodies.push(new foodie(this.foodieToAdd));
    };

    self.delFoodie = function (foodieToDel) {
        self.foodies.remove(foodieToDel);
    };

    self.debug = function () {
        alert(ko.toJSON(self, null, 4));
    };
}

var app = new foodieApp();
ko.applyBindings(app);
于 2013-04-24T23:02:25.153 回答