0

私は初めてノックアウトを試していますが、それを機能させるのに苦労しています。基本的なシナリオは、オートコンプリートを使用して従業員をリストに追加することです。その時も取り除けるようになりたいです。ユーザーが満足したら、[送信]をクリックすると、IDのリストがサーバーに送信され、プロセスの次の部分に進みます。現在、私は追加の従業員を最初に働かせようとしています。

サーバーサイドビューモデルクラスがあります。

public class TrainingListEmployeesViewModel : BaseTrainingViewModel
{
    public TrainingListEmployeesViewModel()
    {
        this.EmployeeList = new List<int>();
        this.ClientEmployeeSelector = new ClientEmployeeSelector();
    }

    public TrainingListEmployeesViewModel(List<int> employeeList, string trainingName, string trainingDescription)
        : base(trainingName, trainingDescription)
    {
        this.EmployeeList = employeeList;
        var dates = new CalendarDates(Utility.GetToday(), Utility.GetToday().AddYears(1));
        this.Cvm = new CalendarViewModel(employeeList.ToList(), dates);
    }

    public List<int> EmployeeList { get; set; }

    public ClientEmployeeSelector ClientEmployeeSelector { get; set; }
}

}

コントローラは次のようになります。

[HttpPost]
        [Authorize(Roles = "Administrator, Trainer, ManagerAccounts, ManagerIT")]
        [ValidateAntiForgeryToken]
        [ValidateOnlyIncomingValuesAttribute]
        public ActionResult Training(TrainingViewModel tvm)
        {
            SessionObjects.TrainingName = tvm.TrainingName;
            SessionObjects.TrainingDescription = tvm.TrainingDescription;
            return this.RedirectToAction("Training", new { employeeId = tvm.EmployeeSelector.SearchTextId });
        }

        [HttpGet]
        [Authorize(Roles = "Administrator, Trainer, ManagerAccounts, ManagerIT")]
        public ActionResult BulkTraining()
        {
            return this.View(new TrainingListEmployeesViewModel());
        }

ビューは次のようになります。

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<SHP.Models.TrainingListEmployeesViewModel>" %>
<%@ Import Namespace="System.Web.Script.Serialization" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Bulk Training
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<form class="employeeListEditor">
    <h3>Allocate or cancel training for the selected employees</h3>
    <table>
        <tr>
            <td style="text-align: right;">Course Name</td>
            <td><%: Html.EditorFor(model => model.TrainingName) %></td>
        </tr>
        <tr>
            <td style="text-align: right;">Description (optional)</td>
            <td><%: Html.TextAreaFor(
               model => model.TrainingDescription, new { maxlength = "255", style = "width:400px;height:100px;" }) %></td>
        </tr>
    </table>
    <%: Html.EditorFor(model => model.ClientEmployeeSelector) %>
    <button data-bind="click: addEmployee">Add</button>
    <div id="displayEmployees" style="margin-top:10px;display: block">
        <table id="employeeDataTable" class="groupBorder">
            <thead>
                <tr>
                    <th></th>
                    <th>Employee</th>
                </tr>
            </thead>
            <tbody data-bind="foreach: employees">
                <tr>
                    <td>
                        <a href="#" data-bind="click: function() { viewModel.removeEmployee($data) }">Remove</a>
                        <input type="hidden" data-bind="value: searchTextId"/>
                    </td>
                    <td><span data-bind="value: searchText"></span></td>
                </tr>               
            </tbody>
        </table>
    </div>
</form>

    <script type="text/javascript">
        function Employee(id, text) {
            var self = this;
            self.searchId = id;
            self.searchText = text;
        }

        var initialData = <%= new JavaScriptSerializer().Serialize(Model) %>;
        function ViewModel() {
            var self = this;
            self.employees = ko.observableArray(initialData.EmployeeList);
            self.searchText = ko.observable(initialData.SearchText);
            self.searchTextId = ko.observable(initialData.SearchTextId);
            self.removeEmployee = function(employee) {
                this.employees.remove(employee);
            };
            self.addEmployee = function() {
                alert(self.searchText);
                this.employees.push(new Employee(self.searchTextId, self.searchText));
            };
            self.save = function() {
                ko.utils.postJson(location.href, { employees: self.employees });
            };
        }
        ko.applyBindings(new ViewModel());
    </script>
</asp:Content>

エディターテンプレートは、オートコンプリートを含むClientEmployeeSelectorのように見えます。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SHP.Models.ClientEmployeeSelector>" %>

        <table class="groupBorder">
            <tr>
                <th colspan="2">Enter 2 or more characters for "<%: Html.LabelFor(model => model.SearchText)%>" and select from the list.</th>
            </tr>
            <tr>
                <td><%: Html.LabelFor(model => model.SearchText)%></td>
                <td><%: Html.AutocompleteFor(model => model.SearchText, controller: "Payroll",
                                            minLength: 2, maxResults: 10,
                                            htmlAttributes: new { style = "color:purple; width:500px;" })%>
                                <%: Html.HiddenFor(model => model.SearchTextId)%>
                                <%: Html.HiddenFor(model => model.SearchText)%>
                </td>
            </tr>
        </table>

エラーメッセージが表示されます。searchTextIdは未定義です。IE開発ツールで何が起こっているかを見ると、searchTextIdは問題なく存在しますが、その値を見つけることは不可能です。では、どうすればこれを機能させることができますか?いくつかの変更を加える必要があると思います。

4

1 に答える 1

1

間違ったプロパティをバインドしているようです。従業員のテーブルを表示したい場合は、foreachバインディングで従業員のプロパティを使用する必要があります。また、オブジェクトを使用する代わりに、バインディングで$parentorオブジェクトを使用することをお勧めします。$rootviewModel

    <tbody data-bind="foreach: employees">
        <tr>
            <td>
                <a href="#" data-bind="click: $parent.removeEmployee">Remove</a>
                <input type="hidden" data-bind="value: searchId"/>
            </td>
            <td><span data-bind="text: searchText"></span></td>
        </tr>               
    </tbody>

ここにフィドルが働いています:http://jsfiddle.net/vyshniakov/yXvDB/2/

しかし、本当にsearchTextId従業員テーブルにビューモデルのプロパティを表示したい場合は、$parentオブジェクトを使用する必要があります:

<input type="hidden" data-bind="value: $parent.searchTextId"/>
于 2012-10-15T14:11:42.170 に答える