0

这里有两个示例:
示例 1:http: //jsfiddle.net/TheMetalDog/yYAFJ/9/
示例 2:http: //jsfiddle.net/TheMetalDog/yYAFJ/11/

在示例 1 中,一个 observable 位于 viewModel 之外,并且当您添加项目时,从选择列表中选择的标题会单独附加到模板项目。

var selectedTitle = ko.observable();

在示例 2 中,可观察对象位于 viewModel 内部,并且所有绑定到可观察对象的项目都会在您添加项目时同步和更新。

viewModel.selectedTitle = ko.observable();

在模块环境中或更具体地说,在 requirejs 中工作时,是否有获得示例 1 行为的推荐策略?

4

2 回答 2

1

目前尚不清楚您的代码试图做什么。似乎您有两个独立的视图模型,并且您希望它们相互交互。如果是这种情况,您可能想要使用postbox。它将允许您将视图模型分开,但仍允许它们相互通信。

因此,您希望获取选定的标题,并在视图模型中创建新项目或子项目时使用它。

只是为了让它不碍事,你真的需要为title你的物品添加一个属性。将项目映射到另一个具有 observable 的对象title

function Item(data) {
    var self = this;
    self.title = ko.observable(data.title); // add a 'title' property to all items
    self.name = ko.observable(data.name);

    // map any existing child items to new Items
    self.childItems = ko.observableArray(ko.utils.arrayMap(data.childitems, function (item) {
        return new Item(item);
    }));
}

我认为最简单的方法是创建一个“add”和“addChild”主题并让您的视图模型订阅它。当您获得该主题的更新时,您可以使用该标题添加新项目。然后从您的外部来源,让它发布您希望使用的标题到适当的主题。

function ViewModel(data) {
    var self = this;

    // ...

    var i = 5;
    function newItem(title) {
        return new Item({
            title: title,
            name: i++,
            childItems: []
        });
    }
    ko.postbox.subscribe('add', function (title) {
        // a title was received for the `add` topic, add it
        self.items.push(newItem(title));
    });
    ko.postbox.subscribe('addChild', function (title) {
        // a title was received for the `addChild` topic, add it
        var firstItem = self.items()[0];
        if (firstItem) {
            firstItem.childItems.push(newItem(title));
        }
    });
}
// add a new item using the selected title
ko.postbox.publish('add', selectedTitle());

// add a new child item using the selected title
ko.postbox.publish('addChild', selectedTitle());

更新了你的小提琴来展示你可能应该做什么。

于 2012-10-31T05:31:54.083 回答
0

Knockout 2.2 的可观察对象的新 peek 函数可以处理这种情况。这是更新的 jsFiddle:http: //jsfiddle.net/TheMetalDog/fD5kF/

不同之处在于.peek()这里添加: <span data-bind="text: $root.selectedTitle.peek()"></span>

于 2012-10-31T19:44:28.750 回答