knockout.js를 ASP.NET MVC ViewModels와 함께 사용하는 방법?


129

하사품

시간이 오래 걸렸지 만 여전히 몇 가지 뛰어난 질문이 있습니다. 현상금을 추가하여 이러한 질문에 대한 답변을 얻을 수 있기를 바랍니다.

  1. knockout.js와 함께 HTML 도우미를 사용하는 방법
  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. 예를 들어 플러그인을 사용하고 싶습니다. 사용자가 요청을 취소하는 것처럼 관찰 가능 항목을 롤백하고 싶습니다. 마지막 값으로 되돌릴 수 있기를 원합니다. 내 연구에서 이것은 편집 가능한 것과 같은 플러그인을 만드는 사람들이 달성 한 것으로 보입니다.

    매핑을 사용하는 경우 이와 같은 것을 어떻게 사용합니까? 나는 실제로 수동 매핑에있는 방법으로 가고 싶지 않다. 가능한 한 작은 인라인 자바 스크립트를 원하고 각 작업의 두 배처럼 보이는 것처럼 각 MVC viewMode 필드를 KO 모델 필드에 매핑하는 것이 었습니다. 왜 그 매핑을 좋아합니까?

  5. 나는 (매핑을 사용하여)이 작업을 쉽게하기 위해 많은 KO 힘을 잃을 것이지만, 반면에 수동 매핑은 많은 작업이 될 것이며 내 견해에 너무 많은 정보가 포함되도록 할 것입니다. 향후 유지 관리가 더 어려워 질 수 있습니다 (MVC 모델에서 속성을 제거하면 KO 뷰 모델에서도 이동해야 함)


원본 게시물

나는 asp.net mvc 3을 사용하고 있으며 꽤 멋지게 보일 때 녹아웃을 찾고 있지만 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; }

}

CourseName과 같은 기본 속성이있는 Vm이 있고 그 위에 간단한 유효성 검사가 있습니다. Vm 모델에는 필요한 경우 다른 뷰 모델도 포함될 수 있습니다.

그런 다음이 Vm을 View에 전달하면 html 도우미를 사용하여 사용자에게 표시 할 수있었습니다.

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

학생 뷰 모델 모음에서 데이터를 가져 오는 foreach 루프 또는 무언가가있을 수 있습니다.

그런 다음 양식을 제출 할 때 jquery를 사용 serialize array하여 뷰 모델에 다시 바인딩하는 컨트롤러 작업 메소드로 보냅니다.

knockout.js를 사용하면 뷰 모델을 얻었을 때 완전히 다르며 모든 예제에서 HTML 도우미를 사용하지 않는 것으로 나타났습니다.

knockout.js와 함께이 두 가지 MVC 기능을 어떻게 사용합니까?

나는 이 비디오를 발견 했고 간략하게 ( 비디오의 마지막 몇 분 @ 18:48) ViewModels에 값이 할당되는 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);
    }

2
방금 다른 비슷한 질문에 대답하기 위해 블로그 게시물을 작성했습니다. roysvork.wordpress.com/2012/12/09/… 귀하의 질문에 완전히 답변하지는 않지만 일이 어떻게 작동하는지에 대한 좋은 아이디어를 제공합니다. 나는 그렇게 멀지 않은 미래에 추가 게시물로 이것을 추적하기를 희망합니다. 게시물에 대한 의견이나 추가 정보가 필요한 경우 여기에 의견을 보내주십시오.
코드를 넘어

답변:


180

나는 당신의 모든 질문을 요약했다고 생각합니다. 내가 뭔가를 놓쳤다면 알려주십시오 ( 한 곳에서 모든 질문을 요약 할 수 있다면 좋을 것입니다 =))

노트. ko.editable추가 된 플러그인 과의 호환성

전체 코드 다운로드

knockout.js와 함께 HTML 도우미를 사용하는 방법

이것은 쉬워요:

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

어디:

  • value: CourseId당신이 바인딩을 나타냅니다 value의 특성 input으로 제어 CourseId모델의 특성 및 스크립트 모델

결과는 다음과 같습니다.

<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" />

문서를 작동시키기 위해 문서가 필요한 이유 (자세한 내용은 첫 번째 편집 참조)

ready모델을 직렬화 하기 위해 이벤트 를 사용해야하는 이유를 아직 이해하지 못하지만 단순히 필요한 것 같습니다 (걱정하지 않아도 됨)

뷰 모델에 녹아웃 매핑을 사용하는 경우 이와 같은 작업을 어떻게 수행합니까? 매핑으로 인해 기능이 없기 때문에.

내가 올바르게 이해한다면 KO 모델에 새로운 방법을 추가해야합니다.

자세한 내용은 섹션-다른 소스에서 매핑-

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

받고있는 경고에 대하여

경고 1 조건부 컴파일이 꺼져 있습니다-> @ Html.Raw

따옴표를 사용해야합니다

ko.editable 플러그인과의 호환성

더 복잡해질 것이라고 생각했지만 모델을 편집 가능하게 만들려면 통합이 정말 쉽다는 것을 알았습니다. 다음 줄을 추가하십시오. (이 경우 서버와 클라이언트에 확장을 추가하면 편집 가능한 것이 간단하게 작동합니다 ...)

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

여기 에서 플러그인에 의해 추가 된 확장을 사용하여 바인딩 을 재생 해야합니다. 예를 들어, 이와 같은 필드 편집을 시작하는 버튼이 있으며이 버튼에서 편집 프로세스를 시작합니다.

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

그런 다음 다음 코드가있는 커밋 및 취소 버튼이 있습니다.

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

마지막으로 필드가 편집 모드인지 여부를 나타내는 하나의 필드가 있습니다. 이것은 단지 enable 속성을 바인딩하는 것입니다.

this.isInEditMode = ko.observable(false);

배열 질문에 대하여

학생 뷰 모델 모음에서 데이터를 가져 오는 foreach 루프 또는 무언가가있을 수 있습니다.

그런 다음 양식을 제출 할 때 jquery를 사용하고 배열을 serialize하고 그것을 viewmodel에 다시 바인딩하는 컨트롤러 작업 메소드로 보냅니다.

다음 예제에서 KO를 사용하여 동일한 작업을 수행 할 수 있습니다. 다음 출력을 작성합니다.

여기에 이미지 설명을 입력하십시오

기본적으로 여기에, 당신은이 목록을 사용하여 만든 Helpers및 KO로 바인더 제본, 그들은 한 dblClick이벤트 해고 할 때, 현재 목록에서 선택한 항목을 제거하고에 게시 다른 목록에 추가하는 것이 바인더 제본 Controller, 각각의 내용을 목록은 JSON 데이터로 전송되고 서버 모델에 다시 첨부됩니다.

너겟 :

외부 스크립트 .

컨트롤러 코드

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

모델

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

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

스크립트

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

참고 : 방금 다음 줄을 추가했습니다.

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

양식을 제출하면 필드가 비활성화되어 값이 서버로 전송되지 않기 때문에 몇 가지 숨겨진 필드를 추가하여 트릭을 수행합니다.


흠 매우 유익합니다. 귀하의 답변과 Pual의 답변에서 편집 가능한 플러그인을 사용하는 방법을 제외하고 거의 모든 질문에 대한 답변을 얻었습니다. 잘만되면 누군가 내가 이것을 어떻게 사용할 수 있는지 알고 있습니다.
chobo2

1
방금 ko.editables플러그인 과의 호환성을 추가 했습니다. 업데이트 된 응답을 확인하거나 원하는 경우 전체 프로젝트를 다운로드하여 로컬로 실행할 수 있습니다.
Jupaol

가능하면 확인하겠습니다. 작동하도록 변경해야합니까? 모든 플러그인에 대해 변경 해야하는지 확인한 다음 내 버전을 유지 해야하는지 궁금합니다.
chobo2

아니. 놀라 울 것입니다. 거의 즉시 사용 가능합니다.
Jupaol

1
감사합니다. 귀하의 답변에서 여러 가지 새로운 전략을 배웠습니다. 명성!
sky-dev

23

ASP.NET MVC 뷰 모델을 자바 스크립트 변수로 직렬화 할 수 있습니다.

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

녹아웃 문서 에는 많은 예제 가 있습니다.


1
예, 사이트에서 대화 형 자습서를 살펴 보았지만 asp.net mvc와는 아무런 관련이 없습니다. 나는 또한 그들이 매핑 플러그인을 가지고 있지만 그것이 어떻게 맞는지 확실하지 않다. 당신의 예제에서 그것을 다른 스크립트에서 녹아웃 모델에 어떻게 묶을 것인가? 나는 가능한 적은 인라인 자바 스크립트를 갖고 싶어한다 (비-바람직하지만 바람직하지 않다)
chobo2

2
어떤 문제를 해결하려고합니까? MVC보기를 원하고 사용 방법에 만족한다면 거기에 충실 할 수 있습니다. 클라이언트 측 데이터 바인딩 및 조작을 원하면 KO가 훌륭한 선택입니다. 이 답변이 보여주는 것처럼 MVC 코드에서 KO 뷰 모델을 생성 할 수 있습니다. vm을 가져 와서 json으로 직렬화합니다. 그런 다음 클라이언트에서 결과를 자바 스크립트 뷰 모델에 매핑 할 수 있습니다. 그런 다음 뷰 모델을 뷰에 바인딩하면 모든 설정이 완료됩니다. 핵심은 MVC와 KO를 원하지 않는 한 어떤 식 으로든 결합 할 필요가 없다는 것입니다. 그것은 모두 해결하려는 문제에 달려 있습니다.
John Papa

1
asp.net mvc와 관련이없는 것이 정상입니다. 녹아웃은 클라이언트 측 프레임 워크입니다. 사용중인 서버 측 언어를 모르거나 신경 쓰지 않습니다. 이 두 프레임 워크는 완전히 분리되어야합니다.
Darin Dimitrov 2016 년

@JohnPapa-나는 지금하는 일을 좋아하지만 새로운 것을 배우는 것도 좋아합니다 (일부 상황에서 KO가 매우 유용 할 수 있음을 알았습니다). 나는 KO가 클라이언트 쪽 스크립트라는 것을 알고 있지만 나는 그들과 함께 일하는 것으로 본다. 현재 뷰 모델과 html 도우미를 사용하여 뷰를 생성합니다. 그래서 KO는 이것과 함께 일할 필요가 있습니다. 예를 들어 편집 대화 상자가 있다고 가정하십시오. db의 값을 어떻게 그 필드에 디자인하고 채우겠습니까? 내 방식을 사용하는 경우 viewModel이있는 html 도우미의보기입니다. 뷰 모델을 채우고 Action Method를 통해 보내어 사용하십시오.
chobo2

1
@ chobo2, knockout은 클라이언트 측 프레임 워크입니다. 클라이언트에서 뷰 모델을 사용하여 클라이언트에서 MVC 패턴을 구현합니다. 서버가 분리되었습니다. 뷰 모델을 사용할 수도 있습니다. 단지 2 개의 다른 장소입니다. 자바 스크립트를 사용하여 클라이언트에서 구현하려는 복잡한 논리가 있으면 녹아웃이 단순화 할 수 있습니다. 그렇지 않으면 솔직히 필요하지 않습니다.
Darin Dimitrov 2016 년

2

서버 매핑 후 추가 계산 속성을 얻으려면 클라이언트 쪽에서 뷰 모델을 추가로 향상시켜야합니다.

예를 들면 다음과 같습니다.

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

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

따라서 원시 JSON에서 매핑 할 때마다 계산 된 속성을 다시 적용해야합니다.

또한 맵핑 플러그인은 앞뒤로 갈 때마다 다시 작성하는 대신 뷰 모델을 점진적으로 업데이트하는 기능을 제공합니다 (의 추가 매개 변수 사용 fromJS).

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

그리고 매핑 된 속성 만 모델에서 증분 데이터 업데이트를 실행합니다. 이에 대한 자세한 내용은 매핑 설명서를 참조하십시오

FluinJSON 패키지 에 대한 Darin의 답변에 대한 의견에서 언급했습니다 . 나는 그 저자이지만 사용 사례는 ko.mapping보다 더 구체적입니다. 나는 일반적으로 뷰 모델이 한 가지 방법 (예 : 서버-> 클라이언트)이고 데이터가 다른 형식 (또는 전혀 아님)으로 다시 게시되는 경우에만 사용합니다. 또는 자바 스크립트 뷰 모델이 서버 모델과 실질적으로 다른 형식이어야하는 경우.


흠 : FluentJSON은 대부분의 시간 내 뷰 모델이 양방향으로 진행되므로 FluentJSON이 아닌 것 같습니다. 내가 편집 가능하다고 언급 한 플러그인을 어떻게 사용할 수 있는지 알고 있습니까? 마지막으로 매핑을 사용하고 뷰 모델을 사용하지 않고 사용하려고하면 어떤 종류의 기능도 손실됩니까?
chobo2

플러그인을 사용하지 않았으므로 확실하지 않습니다. 내가 과거에 한 일은 모든 변경 사항을 구독하고 변경 사항을 푸시하고 실행 취소 할 때 직렬화 된 뷰 모델 상태 스택을 유지하는 것입니다 ( 이 질문 참조 ).
Paul Tyng

매핑은 어떤 기능에서도 당신을 지키지 않습니다. JS와의 매핑을 처리하는 방법에 대한 규칙을 확인하고 준수해야합니다.
Paul Tyng

글에 올린 질문에 대한 대답은 기본적으로 플러그인입니다. 그들이 뷰 모델을 만들고 그들이 만든 기능을 사용하는 것을 볼 때 혼란 스럽습니다 (ko.observableArrayWithUndo ([])). 매핑을하고 있다면 어떻게 해야할지 모르겠습니다. 유일하게 염두에 두는 것은 관찰 할 수 없거나 각 속성을 매핑 한 자체 매핑 (이 시점에서 내가 당연히 의심 할 수있는 것)을 작성하는 것입니다. 그것이 유지 될 수 없게
될까 두려웠다

아 그래, 그 질문에 대한 나의 대답에 대해 이야기하고 있었는데 미안해
Paul Tyng
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.