【问题标题】:KnockoutJs - Observable Binding and ScopeKnockoutJs - 可观察的绑定和范围
【发布时间】:2012-10-31 03:11:40
【问题描述】:

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

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

var selectedTitle = ko.observable();

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

viewModel.selectedTitle = ko.observable();

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

【问题讨论】:

    标签: knockout.js requirejs


    【解决方案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 来演示你可能应该做什么。

    【讨论】:

    • 感谢 Jeff...您提出的解决方案的问题在于,行为仍然是示例 2 而不是示例 1。当您从下拉列表中选择标题时,依赖关系会导致每个条目更新为当前选择的标题,而不是在添加条目时保持选择的标题。我很抱歉没有让问题的细节尽可能清晰。
    • 哦,所以您想在添加项目或子项时使用选定的标题?那很简单。
    【解决方案2】:

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

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

    【讨论】:

    • 不幸的是,这并没有真正的帮助。它不会将所选标题与您添加的项目相关联。该名称显示在视图上,但如果再次渲染视图,您将失去所有这些。
    猜你喜欢
    • 2012-11-02
    • 2017-11-25
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 2014-10-01
    • 2012-04-20
    相关资源
    最近更新 更多