在编辑时更新observableArray项

时间:2013-07-16 07:46:30

标签: knockout.js

jsFiddle example


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

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

  • 制作observableArrayobservable
  • 中的每件商品
  • 在数组上使用.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>

3 个答案:

答案 0 :(得分:3)

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

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

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);
}

希望它有所帮助!

答案 1 :(得分:2)

您的代码运行正常。您所需要的只是更新items数组,使其属性Text可观察

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

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

请检查我的 Working DEMO

答案 2 :(得分:1)

您需要将Text属性转换为observable。 我选择使用ko.mapping来执行此操作。 ko.mapping.fromJS会将所有js属性转换为ko.observables。

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

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));
    };

};

See fiddle