0

我已经在其他地方看到了这个问题的一些解决方案,但还没有找到如何在我的具体情况下完成这项工作。

observableArray 填充一个 html 列表。在列表中,用户可以编辑特定行的值之一。行中要编辑的项目本身就是一个填充下拉列表的 observableArray。当单击行上的编辑按钮时,下拉列表的数组通过 ajax 调用填充(编辑按钮未在下面的代码中显示)。

除了一个重要问题外,我的一切工作正常:到目前为止,下拉列表中的值尚未预先填充。

下面是真实代码在做什么的粗略模型。

如果我在 html 中调用,则填充初始值selectedTeamType但未注册对选择框的进一步更改。如果我调用as just ,则初始值设置不正确,但注册对选择框的进一步更改。selectedTeamType()selectedTeamTypeselectedTeamType

HTML

<table>
    <tr>    <!-- ko foreach: my.TeamViewModel.Teams -->
      <td data-bind="text: TeamID"></td>
      <td data-bind="text: TeamText"></td>
      <td>  <!-- the TeamType will be editable, so we provide a dropdown list, but default to the current value -->
         <select data-bind="options: my.TeamViewModel.TeamTypes, 
             optionsText: 'TeamTypeText', 
             optionsValue: 'TeamTypeID', 
                 value: selectedTeamType"></select>
        </td>
   </tr> <!-- /ko -->
</table>

JAVASCRIPT

var my = my || {};

$(function () {

my.TeamModel = function () {
    var self = this;
    self.TeamID = ko.observable();
         self.TeamText = ko.observable();
    self.TeamTypeID = ko.observable();
    self.selectedTeam = ko.observable(); 
         self.Edit = function () {
            my.TeamViewModel.load_TeamTypes();
        };
};

my.TeamTypesModel = function () {
    var self = this;
    self.TeamTypeID = ko.observable();
    self.TeamTypeText = ko.observable();
};

my.TeamViewModel = function () {
    var Teams = ko.observableArray([]),
        TeamTypes = ko.observableArray([]),
        load_TeamTypes = function () {
            $.ajax({
                      // only part of ajax call displayed here for sake of brevity...              
                                $.each(data, function (i, d) {
                                    TeamTypes.push(new my.TeamTypesModel()
                                            .TeamTypeID(d.TeamTypeID)
                                            .TeamTypeText(d.TeamTypeText)
                                    );
                                });
            });
        },
        load_Teams = function () {
            $.ajax({
                      // only part of ajax call displayed here for sake of brevity...   
                    $.each(data, function (i, d) {
                        Teams.push(new my.TeamModel()
                                .TeamID(d.TeamID)
                                .TeamText(d.TeamText)
                        );
                    });
                }
            });
        };
    return {
        Teams: Teams,
        TeamTypes: TeamTypes,
        load_TeamTypes: load_TeamTypes
    };
} ();

my.TeamViewModel.load_Teams();
ko.applyBindings(my.TeamViewModel);

});

4

3 回答 3

2

是在填充数组selectedTeamType之前设置的吗?my.TeamViewModel.TeamTypes如果是这样,这可能是未设置其初始值的原因。我在您发布的 javascript 中没有看到您设置初始值的任何地方selectedTeamType

更新

您对自己问题的回答证实了我上面的怀疑。每次用户编辑团队时,您是否需要加载团队类型下拉列表?如果每个团队的选择选项都相同,为什么不加载一次呢?

例子:

my.TeamViewModel.load_Teams();
my.TeamViewModel.load_TeamTypes();
ko.applyBindings(my.TeamViewModel);

这样,当用户单击编辑按钮时,选项列表应该已经加载。如果列表中的每个团队都不需要新的团队类型选项列表,它也可以为您的客户端/服务器节省一些汗水。

如果你想保证$.ajax在你做任何事情之前这两个调用都会完成,我建议你研究一下jQuery的$.Deferred方法和promise API。当您有超过 1 个$.ajax调用,并且只有在两者都成功后才需要执行操作时,您可以执行以下操作:

var defer_Teams = $.Deferred();
var defer_TeamTypes = $.Deferred();
$.ajax({ // initiate the server call to get teams
    url: '/teams',
    success: function(data) {
        defer_Teams.resolve(data); // tell the promise API this is ready
    }
});
$.ajax({ // initiate the server call to get team types
    url: '/team-types',
    success: function(data) {
        defer_TeamTypes.resolve(data); // tell the promise API this is ready
    }
});

$.when(defer_Teams, defer_TeamTypes).then(function(teamData, teamTypeData) {

    $.each(teamTypeData, function(i, d) {
        // populate team types array
        // could also do this with ko.mapping instead of $.each
    })

    $.each(teamData, function(i, d) {
        // populate teams array
        // could also do this with ko.mapping instead of $.each
    })

});

假设您的 /teams 呼叫快速返回,但您的 /team-types 呼叫滞后。使用上述方法,在两个调用完成之前不会填充团队数组。在用户单击编辑按钮并获得预填充的选定值之前,您确实需要完成类型调用。

于 2013-04-18T13:44:33.210 回答
1

明显的修复涉及两个步骤:

TeamType首先,在函数中传递对当前项及其当前项的引用Edit

self.Edit = function () {
    var that = this; 
    var _TeamType = self.TeamTypeID();
    my.TeamViewModel.load_TeamTypes(that, _TeamType);
};

然后,最重要的是,将这些引用传递给加载 TeamTypes 的函数,并在加载 TeamTypes 数组之后设置 selectedTeamType;在这种情况下, selectedTeamType 是在completejQuery 的函数中设置的ajax

load_TeamTypes = function (that, _TeamType) {
    $.ajax({
              // only part of ajax call displayed here for sake of brevity...              
                        $.each(data, function (i, d) {
                            TeamTypes.push(new my.TeamTypesModel()
                                    .TeamTypeID(d.TeamTypeID)
                                    .TeamTypeText(d.TeamTypeText)
                            );
                        });

                //...ajax continued
                complete: function () {
                    that.selectedTeamType(_TeamType);
                }
    });
},
于 2013-04-18T13:46:55.960 回答
0

你有没有试过改变你的构造函数来接受 d 喜欢这样

my.TeamTypesModel = function (data) {
        var self = this;
        self.TeamTypeID = ko.observable(data.TeamTypeId);
        self.TeamTypeText = ko.observable(data.TeamTypeText);
    };
于 2013-04-18T02:23:39.263 回答