KnockoutJs - 可观察的绑定和范围

时间:2012-10-31 03:11:41

标签: knockout.js requirejs

以下是两个样本:
样本1:http://jsfiddle.net/TheMetalDog/yYAFJ/9/
样本2:http://jsfiddle.net/TheMetalDog/yYAFJ/11/

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

var selectedTitle = ko.observable();

在示例2中,observable位于viewModel内部,并且在添加项目时,所有绑定到observable的项目都会同步并一起更新。

viewModel.selectedTitle = ko.observable();

在模块环境中工作时是否有建议的策略来获取Sample 1行为,或者更具体地说,是需要?

2 个答案:

答案 0 :(得分:1)

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

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

为了解决这个问题,您确实需要在商品中添加title属性。将项目映射到具有可观察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());

updated your fiddle来证明你应该做的事情。

答案 1 :(得分:0)

Knockout 2.2的observables的新窥视函数可以处理这种情况。这是更新的jsFiddle:http://jsfiddle.net/TheMetalDog/fD5kF/

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