Làm cách nào để sử dụng knoutout.js với ASP.NET MVC ViewModels?


129

Tiền thưởng

Đã được một lúc và tôi vẫn còn một vài câu hỏi nổi bật. Tôi hy vọng bằng cách thêm một tiền thưởng có thể những câu hỏi này sẽ được trả lời.

  1. Làm thế nào để bạn sử dụng trình trợ giúp html với knoutout.js
  2. Tại sao tài liệu đã sẵn sàng cần thiết để làm cho nó hoạt động (xem chỉnh sửa đầu tiên để biết thêm thông tin)

  3. Làm cách nào để làm điều gì đó như thế này nếu tôi đang sử dụng ánh xạ loại trực tiếp với các mô hình chế độ xem của mình? Vì tôi không có chức năng do ánh xạ.

    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. Tôi muốn sử dụng các plugin chẳng hạn, tôi muốn có thể khôi phục các vật thể quan sát như thể người dùng hủy yêu cầu mà tôi muốn để có thể quay lại giá trị cuối cùng. Từ nghiên cứu của tôi, điều này dường như đạt được bởi những người tạo ra các plugin như có thể chỉnh sửa

    Làm thế nào để tôi sử dụng một cái gì đó như thế nếu tôi đang sử dụng bản đồ? Tôi thực sự không muốn đi đến một phương thức mà tôi có trong ánh xạ thủ công trong chế độ xem của mình là tôi ánh xạ từng trường MVC viewMode sang trường mô hình KO vì tôi muốn càng ít javascript nội tuyến càng tốt và nó giống như gấp đôi công việc và đó là tại sao tôi thích ánh xạ đó

  5. Tôi lo ngại rằng để làm cho công việc này trở nên dễ dàng (bằng cách sử dụng ánh xạ) tôi sẽ mất rất nhiều năng lượng KO nhưng mặt khác tôi lo ngại rằng ánh xạ thủ công sẽ chỉ là rất nhiều công việc và sẽ làm cho quan điểm của tôi chứa quá nhiều thông tin và trong tương lai có thể trở nên khó bảo trì hơn (giả sử nếu tôi xóa một thuộc tính trong mô hình MVC thì tôi cũng phải di chuyển nó trong chế độ xem KO)


Bài gốc

Tôi đang sử dụng asp.net mvc 3 và tôi đang tìm kiếm loại trực tiếp vì nó trông khá tuyệt nhưng tôi gặp khó khăn khi tìm hiểu cách nó hoạt động với asp.net mvc đặc biệt là xem các mô hình.

Đối với tôi ngay bây giờ tôi làm một cái gì đó như thế này

 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; }

}

Tôi sẽ có một Vm có một số thuộc tính cơ bản như CourseName và nó sẽ có một số xác nhận đơn giản trên đầu trang của nó. Mô hình Vm cũng có thể chứa các mô hình xem khác trong đó nếu cần.

Sau đó tôi sẽ chuyển Vm này cho View là tôi sẽ sử dụng trình trợ giúp html để giúp tôi hiển thị nó cho người dùng.

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

Tôi có thể có một số vòng lặp foreach hoặc một cái gì đó để lấy dữ liệu ra khỏi bộ sưu tập Mô hình Chế độ xem của sinh viên.

Sau đó, khi tôi gửi biểu mẫu, tôi sẽ sử dụng jquery serialize arrayvà gửi nó đến một phương thức hành động của bộ điều khiển để liên kết nó lại với viewmodel.

Với knoutout.js, tất cả đều khác biệt khi bạn có chế độ xem cho nó và từ tất cả các ví dụ tôi thấy họ không sử dụng trình trợ giúp html.

Làm thế nào để bạn sử dụng 2 tính năng này của MVC với knoutout.js?

Tôi đã tìm thấy video này và nó ngắn gọn (vài phút cuối của video @ 18:48) đi vào cách sử dụng chế độ xem bằng cách cơ bản có một tập lệnh nội tuyến có chế độ xem knockout.js được gán các giá trị trong ViewModel.

Đây có phải là cách duy nhất để làm điều đó? Làm thế nào về ví dụ của tôi với việc có một bộ sưu tập viewmodels trong đó? Tôi có phải có một vòng lặp foreach hoặc một cái gì đó để trích xuất tất cả các giá trị ra và gán nó vào loại trực tiếp không?

Đối với người trợ giúp html, video không nói gì về họ.

Đây là hai lĩnh vực khiến tôi bối rối vì dường như không có nhiều người nói về nó và điều đó khiến tôi bối rối về cách các giá trị ban đầu và mọi thứ đang được xem khi ví dụ chỉ là một ví dụ giá trị được mã hóa cứng.


Biên tập

Tôi đang thử những gì Darin Dimitrov đã đề xuất và điều này dường như hoạt động (tôi đã phải thực hiện một số thay đổi đối với mã của anh ấy). Không chắc tại sao tôi phải sử dụng tài liệu sẵn sàng nhưng bằng cách nào đó mọi thứ vẫn chưa sẵn sàng nếu không có nó.

@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>

Tôi đã phải bọc nó xung quanh một tài liệu jquery sẵn sàng để làm cho nó hoạt động.

Tôi cũng nhận được cảnh báo này. Không chắc chắn tất cả những gì về nó.

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

Vì vậy, tôi có một điểm khởi đầu tôi đoán ít nhất sẽ cập nhật khi tôi thực hiện thêm một số trò chơi xung quanh và cách thức hoạt động của nó.

Tôi đang cố gắng thực hiện các hướng dẫn tương tác nhưng thay vào đó hãy sử dụng ViewModel.

Không chắc chắn làm thế nào để giải quyết những phần này chưa

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

hoặc là

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
    };


Chỉnh sửa 2

Tôi đã có thể tìm ra vấn đề đầu tiên. Không có manh mối về vấn đề thứ hai. Mặc dù vậy. Bất cứ ai có ý tưởng?

 @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>

Bộ điều khiển

  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);
    }

2
Tôi vừa viết một bài đăng trên blog để trả lời một câu hỏi tương tự khác: roysvork.wordpress.com/2012/12/09/NH Nó có thể không trả lời hoàn toàn câu hỏi của bạn, nhưng nó cho bạn ý tưởng tốt về cách mọi thứ có thể hoạt động. Tôi hy vọng sẽ theo dõi điều này với một bài viết tiếp theo trong tương lai không xa. Hãy hỏi tôi bất kỳ câu hỏi nào trong các bình luận trên bài đăng hoặc ở đây nếu bạn cần thêm thông tin.
ngoài mã

Câu trả lời:


180

Tôi nghĩ rằng tôi đã tóm tắt tất cả các câu hỏi của bạn, nếu tôi bỏ lỡ điều gì đó xin vui lòng cho tôi biết ( Nếu bạn có thể tóm tắt tất cả các câu hỏi của bạn ở một nơi sẽ tốt đẹp =))

Ghi chú. Khả năng tương thích với ko.editabletrình cắm thêm

Tải mã đầy đủ

Làm thế nào để bạn sử dụng trình trợ giúp html với knoutout.js

Điều này thật dễ dàng:

@Html.TextBoxFor(model => model.CourseId, new { data_bind = "value: CourseId" })

Ở đâu:

  • value: CourseIdchỉ ra rằng bạn đang ràng buộc thuộc valuetính của inputđiều khiển với thuộc CourseIdtính từ mô hình của bạn và mô hình tập lệnh của bạn

Kết quả là:

<input data-bind="value: CourseId" data-val="true" data-val-number="The field CourseId must be a number." data-val-required="The CourseId field is required." id="CourseId" name="CourseId" type="text" value="12" />

Tại sao tài liệu đã sẵn sàng cần thiết để làm cho nó hoạt động (xem chỉnh sửa đầu tiên để biết thêm thông tin)

Tôi vẫn chưa hiểu lý do tại sao bạn cần sử dụng readysự kiện này để tuần tự hóa mô hình, nhưng có vẻ như nó chỉ đơn giản là bắt buộc (Mặc dù không phải lo lắng về điều đó)

Làm cách nào để làm điều gì đó như thế này nếu tôi đang sử dụng ánh xạ loại trực tiếp với các mô hình chế độ xem của mình? Vì tôi không có chức năng do ánh xạ.

Nếu tôi hiểu chính xác, bạn cần phải thêm một phương thức mới vào mô hình KO, đó là mô hình hợp nhất dễ dàng

Để biết thêm thông tin, trong phần - Lập bản đồ từ các nguồn khác nhau-

function viewModel() {
    this.addStudent = function () {
        alert("de");
    };
};

$(function () {
    var jsonModel = '@Html.Raw(JsonConvert.SerializeObject(this.Model))';
    var mvcModel = ko.mapping.fromJSON(jsonModel);

    var myViewModel = new viewModel();
    var g = ko.mapping.fromJS(myViewModel, mvcModel);

    ko.applyBindings(g);
});

Về cảnh báo bạn đã nhận được

Cảnh báo 1 Quá trình biên dịch có điều kiện bị tắt -> @ Html.Raw

Bạn cần sử dụng dấu ngoặc kép

Khả năng tương thích với trình cắm ko.editable

Tôi nghĩ rằng nó sẽ phức tạp hơn, nhưng hóa ra việc tích hợp thực sự dễ dàng, để làm cho mô hình của bạn có thể chỉnh sửa được, chỉ cần thêm dòng sau: (hãy nhớ rằng trong trường hợp này tôi đang sử dụng mô hình hỗn hợp, từ máy chủ và thêm tiện ích mở rộng trong máy khách và có thể chỉnh sửa đơn giản là hoạt động ... thật tuyệt):

    ko.editable(g);
    ko.applyBindings(g);

Từ đây, bạn chỉ cần chơi với các ràng buộc của mình bằng cách sử dụng các tiện ích mở rộng được thêm bởi trình cắm, ví dụ: tôi có một nút để bắt đầu chỉnh sửa các trường của mình như thế này và trong nút này tôi bắt đầu quá trình chỉnh sửa:

    this.editMode = function () {
        this.isInEditMode(!this.isInEditMode());
        this.beginEdit();
    };

Sau đó, tôi có các nút cam kết và hủy với mã sau đây:

    this.executeCommit = function () {
        this.commit();
        this.isInEditMode(false);
    };
    this.executeRollback = function () {
        if (this.hasChanges()) {
            if (confirm("Are you sure you want to discard the changes?")) {
                this.rollback();
                this.isInEditMode(false);
            }
        }
        else {
            this.rollback();
            this.isInEditMode(false);
        }
    };

Và cuối cùng, tôi có một trường để cho biết các trường có ở chế độ chỉnh sửa hay không, đây chỉ là để ràng buộc thuộc tính enable.

this.isInEditMode = ko.observable(false);

Về câu hỏi mảng của bạn

Tôi có thể có một số vòng lặp foreach hoặc một cái gì đó để lấy dữ liệu ra khỏi bộ sưu tập Mô hình Chế độ xem của sinh viên.

Sau đó, khi tôi gửi biểu mẫu, tôi sẽ sử dụng jquery và tuần tự hóa mảng và gửi nó đến một phương thức hành động của bộ điều khiển sẽ liên kết nó lại với viewmodel.

Bạn có thể làm tương tự với KO, trong ví dụ sau, tôi sẽ tạo đầu ra sau:

nhập mô tả hình ảnh ở đây

Về cơ bản ở đây, bạn có hai danh sách, được tạo bằng cách sử dụng Helpersvà liên kết với KO, chúng có một dblClicksự kiện được liên kết rằng khi bị sa thải, hãy xóa mục đã chọn khỏi danh sách hiện tại và thêm nó vào danh sách khác, khi bạn đăng lên Controller, nội dung của mỗi danh sách được gửi dưới dạng dữ liệu JSON và được đính kèm lại vào mô hình máy chủ

Thợ mỏ:

Kịch bản bên ngoài .

Mã điều khiển

    [HttpGet]
    public ActionResult Index()
    {
        var m = new CourseVM { CourseId = 12, CourseName = ".Net" };

        m.StudentViewModels.Add(new StudentVm { ID = 545, Name = "Name from server", Lastname = "last name from server" });

        return View(m);
    }

    [HttpPost]
    public ActionResult Index(CourseVM model)
    {
        if (!string.IsNullOrWhiteSpace(model.StudentsSerialized))
        {
            model.StudentViewModels = JsonConvert.DeserializeObject<List<StudentVm>>(model.StudentsSerialized);
            model.StudentsSerialized = string.Empty;
        }

        if (!string.IsNullOrWhiteSpace(model.SelectedStudentsSerialized))
        {
            model.SelectedStudents = JsonConvert.DeserializeObject<List<StudentVm>>(model.SelectedStudentsSerialized);
            model.SelectedStudentsSerialized = string.Empty;
        }

        return View(model);
    }

Mô hình

public class CourseVM
{
    public CourseVM()
    {
        this.StudentViewModels = new List<StudentVm>();
        this.SelectedStudents = new List<StudentVm>();
    }

    public int CourseId { get; set; }

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

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

    public string StudentsSerialized { get; set; }
    public string SelectedStudentsSerialized { get; set; }
}

public class StudentVm
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Lastname { get; set; }
}

Trang CSHTML

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>CourseVM</legend>

        <div>
            <div class="editor-label">
                @Html.LabelFor(model => model.CourseId)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(model => model.CourseId, new { data_bind = "enable: isInEditMode, value: CourseId" })
                @Html.ValidationMessageFor(model => model.CourseId)
            </div>

            <div class="editor-label">
                @Html.LabelFor(model => model.CourseName)
            </div>
            <div class="editor-field">
                @Html.TextBoxFor(model => model.CourseName, new { data_bind = "enable: isInEditMode, value: CourseName" })
                @Html.ValidationMessageFor(model => model.CourseName)
            </div>
            <div class="editor-label">
                @Html.LabelFor(model => model.StudentViewModels);
            </div>
            <div class="editor-field">

                @Html.ListBoxFor(
                    model => model.StudentViewModels,
                    new SelectList(this.Model.StudentViewModels, "ID", "Name"),
                    new
                    {
                        style = "width: 37%;",
                        data_bind = "enable: isInEditMode, options: StudentViewModels, optionsText: 'Name', value: leftStudentSelected, event: { dblclick: moveFromLeftToRight }"
                    }
                )
                @Html.ListBoxFor(
                    model => model.SelectedStudents,
                    new SelectList(this.Model.SelectedStudents, "ID", "Name"),
                    new
                    {
                        style = "width: 37%;",
                        data_bind = "enable: isInEditMode, options: SelectedStudents, optionsText: 'Name', value: rightStudentSelected, event: { dblclick: moveFromRightToLeft }"
                    }
                )
            </div>

            @Html.HiddenFor(model => model.CourseId, new { data_bind="value: CourseId" })
            @Html.HiddenFor(model => model.CourseName, new { data_bind="value: CourseName" })
            @Html.HiddenFor(model => model.StudentsSerialized, new { data_bind = "value: StudentsSerialized" })
            @Html.HiddenFor(model => model.SelectedStudentsSerialized, new { data_bind = "value: SelectedStudentsSerialized" })
        </div>

        <p>
            <input type="submit" value="Save" data-bind="enable: !isInEditMode()" /> 
            <button data-bind="enable: !isInEditMode(), click: editMode">Edit mode</button><br />
            <div>
                <button data-bind="enable: isInEditMode, click: addStudent">Add Student</button>
                <button data-bind="enable: hasChanges, click: executeCommit">Commit</button>
                <button data-bind="enable: isInEditMode, click: executeRollback">Cancel</button>
            </div>
        </p>
    </fieldset>
}

Chữ viết

<script src="@Url.Content("~/Scripts/jquery-1.7.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout-2.1.0.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout.mapping-latest.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/ko.editables.js")" type="text/javascript"></script>

<script type="text/javascript">
    var g = null;
    function ViewModel() {
        this.addStudent = function () {
            this.StudentViewModels.push(new Student(25, "my name" + new Date(), "my last name"));
            this.serializeLists();
        };
        this.serializeLists = function () {
            this.StudentsSerialized(ko.toJSON(this.StudentViewModels));
            this.SelectedStudentsSerialized(ko.toJSON(this.SelectedStudents));
        };
        this.leftStudentSelected = ko.observable();
        this.rightStudentSelected = ko.observable();
        this.moveFromLeftToRight = function () {
            this.SelectedStudents.push(this.leftStudentSelected());
            this.StudentViewModels.remove(this.leftStudentSelected());
            this.serializeLists();
        };
        this.moveFromRightToLeft = function () {
            this.StudentViewModels.push(this.rightStudentSelected());
            this.SelectedStudents.remove(this.rightStudentSelected());
            this.serializeLists();
        };
        this.isInEditMode = ko.observable(false);
        this.executeCommit = function () {
            this.commit();
            this.isInEditMode(false);
        };
        this.executeRollback = function () {
            if (this.hasChanges()) {
                if (confirm("Are you sure you want to discard the changes?")) {
                    this.rollback();
                    this.isInEditMode(false);
                }
            }
            else {
                this.rollback();
                this.isInEditMode(false);
            }
        };
        this.editMode = function () {
            this.isInEditMode(!this.isInEditMode());
            this.beginEdit();
        };
    }

    function Student(id, name, lastName) {
        this.ID = id;
        this.Name = name;
        this.LastName = lastName;
    }

    $(function () {
        var jsonModel = '@Html.Raw(JsonConvert.SerializeObject(this.Model))';
        var mvcModel = ko.mapping.fromJSON(jsonModel);

        var myViewModel = new ViewModel();
        g = ko.mapping.fromJS(myViewModel, mvcModel);

        g.StudentsSerialized(ko.toJSON(g.StudentViewModels));
        g.SelectedStudentsSerialized(ko.toJSON(g.SelectedStudents));

        ko.editable(g);
        ko.applyBindings(g);
    });
</script>

Lưu ý: Tôi vừa thêm những dòng này:

        @Html.HiddenFor(model => model.CourseId, new { data_bind="value: CourseId" })
        @Html.HiddenFor(model => model.CourseName, new { data_bind="value: CourseName" })

Bởi vì khi tôi gửi biểu mẫu, các trường của tôi bị vô hiệu hóa, do đó, các giá trị không được truyền đến máy chủ, đó là lý do tại sao tôi đã thêm một vài trường ẩn để thực hiện thủ thuật


Hmm rất nhiều thông tin. Từ câu trả lời của bạn và câu trả lời của Pual, tôi nghĩ rằng tôi gần như đã trả lời tất cả các câu hỏi của mình ngoại trừ cách sử dụng các plugin như có thể chỉnh sửa. Hy vọng ai đó biết làm thế nào tôi có thể sử dụng này.
chobo2

1
Tôi vừa thêm khả năng tương thích với ko.editablesplugin, bạn có thể kiểm tra phản hồi được cập nhật hoặc nếu bạn muốn, bạn có thể tải xuống toàn bộ dự án để chạy cục bộ
Jupaol

Tôi sẽ kiểm tra nó khi tôi có thể. Có phải thay đổi nhiều để làm cho nó hoạt động? Tôi tự hỏi nếu với mỗi plugin tôi tìm thấy nếu tôi sẽ phải thay đổi nó và sau đó phải giữ phiên bản của riêng tôi.
chobo2

Không. Bạn sẽ ngạc nhiên, nó gần như vượt
trội

1
Cảm ơn một người đàn ông, tôi đã học được một số chiến lược mới từ phản ứng của bạn. Thanh danh!
bầu trời

23

Bạn có thể tuần tự hóa mô hình khung nhìn ASP.NET MVC của mình thành một biến 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>

Có rất nhiều ví dụ trong tài liệu loại trực tiếp mà bạn có thể trải qua.


1
Vâng, tôi đã xem qua hướng dẫn tương tác họ có trên trang web nhưng tôi thực sự không bao giờ thấy bất cứ điều gì để làm với asp.net mvc. Tôi thấy họ cũng có một số plugin lập bản đồ nhưng không chắc nó phù hợp như thế nào. Trong ví dụ của bạn, bạn sẽ liên kết nó với mô hình loại trực tiếp như thế nào (trong một kịch bản khác). Tôi thực sự muốn có càng ít javascript nội tuyến càng tốt (không thích hợp hơn nhưng tôi đoán là không thể)
chobo2

2
Vấn đề gì bạn đang cố gắng giải quyết? Nếu bạn muốn có chế độ xem MVC và hài lòng với cách sử dụng chúng, bạn có thể sử dụng nó. Nếu bạn muốn ràng buộc và thao tác dữ liệu phía máy khách, thì KO là một lựa chọn tuyệt vời. Bạn có thể tạo viewmodel KO từ mã MVC của mình khi câu trả lời này hiển thị. Nó lấy vm và tuần tự hóa nó thành json. Sau đó, trên máy khách, bạn có thể ánh xạ kết quả vào chế độ xem javascript. Sau đó, liên kết khung nhìn với khung nhìn và bạn đã hoàn tất. Điều quan trọng là MVC và KO không cần phải được ghép nối theo bất kỳ cách nào, trừ khi bạn muốn chúng được. Tất cả phụ thuộc vào vấn đề bạn đang cố gắng giải quyết.
John Papa

1
Thật bình thường khi bạn không thấy bất cứ điều gì để làm với asp.net mvc. Knockout là một khung phía khách hàng. Nó không biết và cũng không quan tâm bạn đang sử dụng ngôn ngữ phía máy chủ nào. Hai khung đó nên được tách rời hoàn toàn.
Darin Dimitrov

@JohnPapa - Tôi thích cách tôi làm mọi thứ bây giờ nhưng tôi cũng thích học những điều mới (tôi thấy rằng KO có thể rất hữu ích trong một số tình huống). Tôi biết KO là kịch bản phía máy khách nhưng với tôi, tôi thấy họ làm việc cùng nhau. Tôi hiện đang tạo các chế độ xem của mình bằng cách sử dụng các mô hình xem và trình trợ giúp html. Vì vậy, trong tâm trí của tôi KO cần phải làm việc với điều này. Ví dụ, bạn có hộp thoại chỉnh sửa. Làm thế nào bạn sẽ thiết kế và điền các giá trị từ một db vào các trường đó. Nếu tôi đang sử dụng theo cách của mình thì đó sẽ là chế độ xem của những người trợ giúp html có viewModel. Sẽ điền vào viewmodel và gửi nó thông qua Phương thức hành động và sử dụng nó.
chobo2

1
@ chobo2, loại trực tiếp là khung khách hàng. Nó sử dụng các mô hình xem trên máy khách để triển khai mẫu MVC trên máy khách. Các máy chủ được tách rời. Bạn cũng có thể sử dụng mô hình xem trên nó. Đó chỉ là 2 nơi khác nhau. Nếu bạn có một số logic phức tạp mà bạn muốn triển khai trên máy khách bằng cách sử dụng javascript thì việc loại bỏ có thể đơn giản hóa việc này. Mặt khác, thành thật mà nói, bạn không cần nó.
Darin Dimitrov

2

Để đạt được các thuộc tính được tính toán bổ sung sau khi ánh xạ máy chủ, bạn sẽ cần nâng cao hơn nữa chế độ xem của mình ở phía máy khách.

Ví dụ:

var viewModel = ko.mapping.fromJS(model);

viewModel.capitalizedName = ko.computed(function() {...}, viewModel);

Vì vậy, mỗi khi bạn ánh xạ từ JSON thô, bạn sẽ cần phải áp dụng lại các thuộc tính được tính toán.

Ngoài ra, plugin ánh xạ cung cấp khả năng cập nhật dần dần một chế độ xem thay vì tạo lại nó mỗi khi bạn qua lại (sử dụng một tham số bổ sung trong fromJS):

// Every time data is received from the server:
ko.mapping.fromJS(data, viewModel);

Và điều đó thực hiện cập nhật dữ liệu gia tăng trên mô hình chỉ các thuộc tính của bạn được ánh xạ. Bạn có thể đọc thêm về điều đó trong tài liệu bản đồ

Bạn đã đề cập trong các nhận xét về Darin trả lời gói FluentJSON . Tôi là tác giả của điều đó, nhưng trường hợp sử dụng của nó cụ thể hơn ko.maps. Tôi thường chỉ sử dụng nó nếu chế độ xem của bạn là một chiều (ví dụ: máy chủ -> máy khách) và sau đó dữ liệu được đăng lại ở một số định dạng khác nhau (hoặc hoàn toàn không). Hoặc nếu viewmodel javascript của bạn cần phải ở định dạng khác với mô hình máy chủ của bạn.


Hmm, tôi đoán có lẽ FluentJSON không dành cho tôi vì chế độ xem của tôi hầu hết thời gian đi cả hai chiều (tôi thường gửi nó trở lại qua json và sau đó liên kết nó với viewmodel trong tham số phương thức hành động). Bạn có biết làm thế nào tôi có thể sử dụng các plugin mà tôi đã đề cập như có thể chỉnh sửa không? Cuối cùng, tôi có mất bất kỳ loại chức năng nào bằng cách sử dụng ánh xạ và cố gắng sử dụng chế độ xem của tôi so với không sử dụng nó không?
chobo2

Tôi chưa sử dụng bất kỳ plugin nào nên không chắc chắn. Những gì tôi đã làm trong quá khứ chỉ là đăng ký mọi thay đổi và giữ một loạt các trạng thái viewmodel được tuần tự hóa mà tôi sẽ đẩy vào thay đổi và bật lên hoàn tác ( xem câu hỏi này ).
Paul Tyng

ánh xạ không giữ bạn khỏi bất kỳ chức năng nào, bạn chỉ cần đảm bảo và tuân thủ các quy ước của nó về cách nó xử lý ánh xạ đến và từ JS để làm cho tất cả hoạt động tốt với nhau.
Paul Tyng

Vâng, câu trả lời được chấp nhận cho câu hỏi bạn đã đăng về cơ bản là plugin sẽ là gì. Đó là điều khiến tôi bối rối khi bạn có thể thấy họ tạo ra một khung nhìn và sau đó sử dụng chức năng của họ mà họ đã tạo ra (ko.observableArrayWithUndo ([])). Nếu tôi đang lập bản đồ, tôi không biết làm thế nào. Điều duy nhất nảy ra là viết bản đồ của riêng tôi (điều mà tôi nghi ngờ là tôi có thể đúng vào lúc này) mà không thể quan sát được hoặc ánh xạ từng thuộc tính ra nhưng về cơ bản tôi đã có các chế độ xem trùng lặp một cho máy chủ và một cho khách hàng và tôi sợ rằng điều đó sẽ trở nên không thể nhận ra
chobo2

Ah yeah xin lỗi tôi đã nói về câu trả lời của tôi cho câu hỏi đó, xin lỗi nên đã liên kết trực tiếp.
Paul Tyng
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.