在Knockout URL中使用表单数据

时间:2013-12-11 15:51:38

标签: javascript jquery razor knockout.js asp.net-web-api

我有一个名为StaffContribution的资源,用于记录工作人员将为特定活动贡献多少小时。

我用于创建新Staffcontribution的Web Api操作是:People / {StaffID} / Activities / {ActivityID} / StaffContributions

我有一个MVC客户端,其活动详细信息页面显示所有StaffContributions,并允许通过Knockout添加其他工作人员。它包含以下形式:

<form id="addStaffContribution" data-bind="submit: create">
    <fieldset>
        <legend>Add Contributor</legend>

        @Html.HiddenFor(model => model.StaffID)

        <div class="editor-label">
            @Html.LabelFor(model => model.DisplayName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.DisplayName)
            @Html.ValidationMessageFor(model => model.DisplayName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Hours)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Hours)
            @Html.ValidationMessageFor(model => model.Hours)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
</form>

以下Knockout VM:

function StaffContributionsViewModel() {
    var self = this;
    self.staffContributions = ko.observableArray();

    // This is what I need to fill in. ActivityID is in the ViewBag, StaffID is supplied in the form.
    var PostUrl='People/{StaffID}/Activities/{ActivityID}/StaffContributions'; 

    self.create = function (formElement) {
        $(formElement).validate();
        if ($(formElement).valid()) {
            $.post(PostUrl, $(formElement).serialize(), null, "json")
                .done(function (newContribution) { self.staffContributions.push(newContribution); });
        }
    }
    //... Put, Delete etc here.
}

我需要做的是使用ViewBag.ActivityID和用户在表单中提供的StaffID构建PostUrl。我以前通过在DTO而不是URL中包含StaffID来工作,但我觉得StaffID是URL的一部分更有意义,因为StaffContribution本质上是Staff和Activity之间的连接表。

有人可以告诉我这是如何实现的吗?

2 个答案:

答案 0 :(得分:1)

简单:

var PostUrl = 'People/@(ViewBag.StaffID)/Activities/@(ViewBag.ActivityID)/StaffContributions';

但是,您希望将此变量移出视图模型并将其命名为正确名称,以免在全局范围内发生冲突。你需要保留这些JS内联,但其余代码可以进入外部文件。

另外,请不要将Knockout与jQuery混淆。 $.post是一个jQuery方法。它与Knockout无关。

更新

有很多不同的方法来处理这个,只需选择一个。可能最有效的方法是简单地将ViewBag.ActivityID保存到JS变量,然后在create方法中构造URL:

MyNamespace.ActivityID = '@ViewBag.ActivityID';

...

self.create = function (formElement) {
    var PostUrl = 'People/' + formElement.val() + '/Activities/' + MyNamespace.ActivityID + '/StaffContributions'

    $(formElement).validate();
    if ($(formElement).valid()) {
        $.post(PostUrl, $(formElement).serialize(), null, "json")
            .done(function (newContribution) { self.staffContributions.push(newContribution); });
    }
}

答案 1 :(得分:0)

我猜你可以这样:

<input type="hidden" val="@model.StaffID" id="staff-id" />

...

var staffId = parseInt($('#staff-id').val(), 10);

然后将它附加到你的字符串中。


或者就像$('#addStaffContribution').find('input[type=hidden]').val()一样,你可以保留MVC绑定