6

jsFiddle 示例


我有一个observableArray可选项目(在表格中)。我想要做的是在点击表格行时打开一个模式,用项目详细信息填充模式,允许编辑项目,然后保存更改 - 在observableArray. 到目前为止,我已经完成了所有其他工作,但似乎无法更新数组项。

到目前为止,我已经尝试过:

  • 使每个observableArray项目observable
  • 在数组上使用.replace来更新项目 - 这确实有效,但感觉不对
  • 发回更新的项目,将其应用到数据库并重新绑定数组 - 虽然这可行,但这不会破坏 KnockoutJS 的要点吗?

我在上面提供了一个 jsFiddle 链接,它演示了我想要实现的目标。

查看模型和初始化

随意就我如何初始化提出任何建议self.selectItem我目前正处于 KnockoutJS 的学习阶段,并通过玩模拟项目来做到这一点,所以我愿意接受所有建设性的批评。

var items = [{
    Id: 1,
    Text: 'First item'
}, {
    Id: 2,
    Text: 'Second item'
}];

var viewModel = function (items) {
    var self = this;
    self.items = ko.observableArray(items);
    self.selectedItemId = ko.observable();
    self.item = ko.observable();
    self.selectItem = function (item) {
        for (var i = 0; i < self.items().length; i++) {
            if (self.items()[i].Id === self.selectedItemId()) {
                self.item(self.items()[i]);
                break;
            }
        }
    };
};

ko.applyBindings(new viewModel(items));

标记绑定

<select data-bind="options: items, optionsCaption: 'Select...', optionsText: 'Text', optionsValue: 'Id', value: selectedItemId, event: { change: selectItem }"></select>
<div data-bind="if: item">
    <input type="text" data-bind="value: item().Text" />
</div>
<table>
    <thead>
        <tr>
            <th>Text</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: items">
        <tr>
            <td data-bind="text: $data.Text"></td>
        </tr>
    </tbody>
</table>
4

3 回答 3

3

当您更改“文本”属性时,我创建了一个新的jsFiddle示例,其中包含项目的更新。

您的问题是“项目”变量。如果要更新项目属性,则必须使它们可观察:

var observableItems = [
    new ItemViewModel(1, "First item"),
    new ItemViewModel(2, "Second item")
];

function ItemViewModel(id, text){
    var self = this;
    self.Id = ko.observable(id);
    self.Text = ko.observable(text);
}

希望能帮助到你 !

于 2013-07-16T08:05:34.277 回答
2

你的代码工作正常。您需要做的就是更新您的items数组以使其属性Text可观察

var items = [{
    Id: 1,
    Text: ko.observable('First item')
}, {
    Id: 2,
    Text: ko.observable('Second item')
}];

我添加了小代码来检查所选选项是否为“选择...”,然后清除该项目以隐藏输入文本。

请检查我的工作演示

于 2013-07-16T10:01:52.093 回答
1

您需要将 Text 属性转换为可观察的。我选择使用ko.mapping来做。ko.mapping.fromJS 会将所有 js 属性转换为 ko.observables。

在 post 方法中,我将可观察的视图模型转换为原始数据。

var viewModel = function (items) {
    var self = this;
    // to observable
    self.items = ko.mapping.fromJS(items);
    self.selectedItemId = ko.observable();
    self.item = ko.observable();
    self.selectItem = function (item) {
        for (var i = 0; i < self.items().length; i++) {
            if (self.items()[i].Id() === self.selectedItemId()) {
                self.item(self.items()[i]);
                break;
            }
        }
    };

    self.post =  function(){
    // to raw js object
        var data =  ko.mapping.toJS(self.items);
        console.log(JSON.stringify(data));
    };

};

见小提琴

于 2013-07-16T08:24:54.727 回答