[Asp.net-Mvc] 如何使用ASP.NET MVC ViewModels的knockout.js?



Answers

你可以將你的ASP.NET MVC視圖模型序列化為一個javascript變量:

@model CourseVM
<script type="text/javascript">
    var model = @Html.Raw(Json.Encode(Model));
    // go ahead and use the model javascript variable to bind with ko
</script>

淘汰賽文檔中有很多例子可以通過。

Question

賞金

已經有一段時間了,我還有一些未解決的問題。 我希望通過增加賞金,也許這些問題將得到回答。

  1. 你如何使用knockout.js的html helper
  2. 為什麼需要準備文檔才能使其工作(請參閱第一次編輯以獲取更多信息)

  3. 如果我使用視圖模型使用挖空映射,我該如何做這樣的事情? 由於我沒有映射功能。

    function AppViewModel() {
    
        // ... leave firstName, lastName, and fullName unchanged here ...
    
        this.capitalizeLastName = function() {
    
        var currentVal = this.lastName();        // Read the current value
    
        this.lastName(currentVal.toUpperCase()); // Write back a modified value
    
    };
    
  4. 我希望使用插件作為實例,我希望能夠回滾observables,就像用戶取消請求一樣,我希望能夠返回到最後一個值。 從我的研究來看,這似乎是通過製作editables插件等人來實現的

    如果我使用映射,我該如何使用類似的東西? 我真的不想去一個方法,在我看來,手動映射是我將每個MVC viewMode字段映射到一個KO模型字段,因為我想盡可能少用內聯javascript,而且看起來像是工作的兩倍,這就是為什麼我喜歡那個映射。

  5. 我擔心為了使這項工作變得簡單(通過使用映射),我將失去很多KO的力量,但另一方面,我擔心手工映射只是很多工作,並會使我的觀點包含太多的信息,可能會在未來變得更難以維護(比如說,如果我在MVC模型中刪除了一個屬性,我必須在KO視圖模型中移動它)

原始帖子

我正在使用asp.net mvc 3,並且我正在尋找knockout,因為它看起來很酷,但我很難弄清楚它是如何與asp.net mvc尤其是視圖模型一起工作的。

對我來說,我現在正在做這樣的事情

 public class CourseVM
    {
        public int CourseId { get; set; }
        [Required(ErrorMessage = "Course name is required")]
        [StringLength(40, ErrorMessage = "Course name cannot be this long.")]
        public string CourseName{ get; set; }


        public List<StudentVm> StudentViewModels { get; set; }

}

我會有一個Vm,它具有一些像CourseName這樣的基本屬性,並且它會有一些簡單的驗證。 如果需要,Vm模型也可能包含其他視圖模型。

然後我會將這個Vm傳遞給View,我將使用HTML幫助器來幫助我將它顯示給用戶。

@Html.TextBoxFor(x => x.CourseName)

我可能有一些foreach循環或某些東西來從學生視圖模型的集合中獲取數據。

然後,當我提交表單時,我會使用jquery和serialize array並將其發送給控制器操作方法,該方法會將其綁定回視圖模型。

隨著knockout.js,它是所有不同,因為你現在有它的視圖模型,並從我看到他們不使用HTML助手的所有例子。

你如何使用MVC的這兩個特性與knockout.js?

我發現這個視頻並簡要地介紹了視頻模型(最後幾分鐘的視頻@ 18:48),它基本上有一個內置腳本,它具有knockout.js視圖模型,該視圖模型被分配ViewModel中的值。

這是唯一的方法嗎? 在我的例子中有一個視圖模型的集合呢? 我必須有一個foreach循環或其他東西來提取所有的值並將其分配到淘汰賽中嗎?

至於html助手,視頻並沒有提到他們。

這兩個領域讓我感到困惑,因為並不是很多人似乎都在討論這個問題,並且讓我對初始值和所有事物如何進入視圖感到困惑,因為當時的例子只是一些硬編碼的示例。

編輯

我正在嘗試Darin Dimitrov提出的建議,這看起來很有效(儘管我不得不對他的代碼做一些修改)。 不知道為什麼我必須使用文檔準備,但不知何故,沒有它,一切都沒有準備好。

@model MvcApplication1.Models.Test

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>Index</title>
    <script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
    <script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
    <script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
   <script type="text/javascript">

   $(function()
   {
      var model = @Html.Raw(Json.Encode(Model));


// Activates knockout.js
ko.applyBindings(model);
   });

</script>

</head>
<body>
    <div>
        <p>First name: <strong data-bind="text: FirstName"></strong></p>
        <p>Last name: <strong data-bind="text: LastName"></strong></p>
        @Model.FirstName , @Model.LastName
    </div>
</body>
</html>

我不得不將它包裝在一個jquery文檔中,以使其正常工作。

我也得到這個警告。 不知道它是什麼。

Warning 1   Conditional compilation is turned off   -> @Html.Raw

所以我有一個起點,我想至少會在更多的時候更新,以及這是如何工作的。

我正在嘗試通過交互式教程,而是使用ViewModel。

不知道如何解決這些部分

function AppViewModel() {
    this.firstName = ko.observable("Bert");
    this.lastName = ko.observable("Bertington");
}

要么

function AppViewModel() {
    // ... leave firstName, lastName, and fullName unchanged here ...

    this.capitalizeLastName = function() {
        var currentVal = this.lastName();        // Read the current value
        this.lastName(currentVal.toUpperCase()); // Write back a modified value
    };

編輯2

我能弄清楚第一個問題。 沒有關於第二個問題的線索。 儘管如此。 任何人有任何想法?

 @model MvcApplication1.Models.Test

    @{
        Layout = null;
    }

    <!DOCTYPE html>

    <html>
    <head>
        <title>Index</title>
        <script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
        <script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
        <script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
       <script type="text/javascript">

       $(function()
       {
        var model = @Html.Raw(Json.Encode(Model));
        var viewModel = ko.mapping.fromJS(model);
        ko.applyBindings(viewModel);

       });

    </script>

    </head>
    <body>
        <div>
            @*grab values from the view model directly*@
            <p>First name: <strong data-bind="text: FirstName"></strong></p>
            <p>Last name: <strong data-bind="text: LastName"></strong></p>

            @*grab values from my second view model that I made*@
            <p>SomeOtherValue <strong data-bind="text: Test2.SomeOtherValue"></strong></p>
            <p>Another <strong data-bind="text: Test2.Another"></strong></p>

            @*allow changes to all the values that should be then sync the above values.*@
            <p>First name: <input data-bind="value: FirstName" /></p>
            <p>Last name: <input data-bind="value: LastName" /></p>
            <p>SomeOtherValue <input data-bind="value: Test2.SomeOtherValue" /></p>
            <p>Another <input data-bind="value: Test2.Another" /></p>

           @* seeing if I can do it with p tags and see if they all update.*@
            <p data-bind="foreach: Test3">
                <strong data-bind="text: Test3Value"></strong> 
            </p>

     @*took my 3rd view model that is in a collection and output all values as a textbox*@       
    <table>
        <thead><tr>
            <th>Test3</th>
        </tr></thead>
          <tbody data-bind="foreach: Test3">
            <tr>
                <td>    
                    <strong data-bind="text: Test3Value"></strong> 
<input type="text" data-bind="value: Test3Value"/>
                </td>
            </tr>    
        </tbody>
    </table>

調節器

  public ActionResult Index()
    {
              Test2 test2 = new Test2
        {
            Another = "test",
            SomeOtherValue = "test2"
        };

        Test vm = new Test
        {
            FirstName = "Bob",
            LastName = "N/A",
             Test2 = test2,

        };
        for (int i = 0; i < 10; i++)
        {
            Test3 test3 = new Test3
            {
                Test3Value = i.ToString()
            };

             vm.Test3.Add(test3);
        }

        return View(vm);
    }



Links