【问题标题】:Initial evaluation in knockout binding when using mapping plugin使用映射插件时敲除绑定的初始评估
【发布时间】:2013-03-03 21:29:38
【问题描述】:

我正在尝试使用单页应用程序示例(淘汰教程)和映射插件来创建用户可以单击(选择)的项目列表。我需要从一开始就选择一个默认项目,这是映射插件不起作用的地方,尽管它适用于裸淘汰赛。我错过了什么吗?或者你如何驯服映射插件?

HTML 部分:

<ul data-bind="foreach: gamePlayers">
    <li class="clickable" data-bind="
              text: playerName, 
              css: { selected: playerId == $root.chosenPlayerId() },                              
              click: $root.selectPlayer">
    </li>
</ul>

JS 常用部分:

var dataJS = {
    gamePlayers: [{playerId:1, playerName:"Sun"},{playerId:2,playerName:"Moon"}],
    playerActive:1
};

确实有效的JS:

function GameViewModel(data) {
    // Data
    var self = this;
    self.gamePlayers = ko.observableArray(data.gamePlayers);
    self.chosenPlayerId = ko.observable();

    // Behaviours    
    self.selectPlayer = function (player) { self.chosenPlayerId(player.playerId); };
    self.selectPlayer(data.gamePlayers[0]);
}

ko.applyBindings(new GameViewModel(dataJS));

不工作的JS:

my.vmPlayers = {};

function MyViewModel (data) {
    var self = this;
    ko.mapping.fromJS(data, {}, self);
    self.chosenPlayerId = ko.observable();
    self.selectPlayer = function (player) { self.chosenPlayerId(player.playerId); };
    self.selectPlayer(data.gamePlayers[0]);
}

var mapping = {
    create: function (options) {
        return new MyViewModel(options.data);
    }
};

my.vmPlayers = ko.mapping.fromJS(dataJS, mapping);
ko.applyBindings(my.vmPlayers);

它如何不起作用的示例http://jsfiddle.net/HeroEja/43AtS/

所以这个绑定 css: { selected: playerId == $root.chosenPlayerId() } 不会在初始页面加载时进行评估。知道为什么非常感谢!

【问题讨论】:

    标签: knockout.js knockout-mapping-plugin


    【解决方案1】:

    主要问题是由这行引起的:

    self.chosenPlayerId(data.playerActive);
    

    因为在这种情况下data 不会是 JS 对象,但 data 本身持有 JSON 字符串 所以data.playerActive 将返回 undefined 并且您的初始选择将不起作用。

    你需要的是:

    self.chosenPlayerId(self.playerActive());  
    

    因为无论如何您都将数据映射到 selfko.mapping.fromJS(data, {}, self);

    由于映射插件playerId 将是可观察的,因此您需要相应地更改您的用法以使其工作

    所以在你的 css 绑定中:

    css: { selected: playerId() == $root.chosenPlayerId() }
    

    在你的selectPlayer 方法中:

    self.selectPlayer = function (player) {
        self.chosenPlayerId(player.playerId());
    };
    

    一个固定的演示JSFiddle

    【讨论】:

    • 太棒了!非常感谢!您如何跟踪绑定中是否需要括号?
    • 如果你没有 observable 你不需要括号,这是简单的部分。如果您的绑定中有可观察对象,则如果您直接使用可观察对象,则不需要括号,例如css: { selected: someobservable } 但如果绑定中有 css: { selected: playerId() == $root.chosenPlayerId() } 之类的表达式,则需要去掉括号。
    • 对……这很有道理。感谢您的帮助!
    猜你喜欢
    • 2013-06-01
    • 1970-01-01
    • 2014-01-21
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 2011-11-21
    相关资源
    最近更新 更多