Knockout.js ASP.NET MVC ViewModels ile nasıl kullanılır?


129

Ödül

Uzun zaman oldu ve hala birkaç önemli sorum var. Umarım bir ödül ekleyerek belki bu sorular cevaplanır.

  1. Knockout.js ile html yardımcılarını nasıl kullanıyorsunuz?
  2. Çalışması için belge neden hazırdı (daha fazla bilgi için ilk düzenlemeye bakın)

  3. Görünüm modellerimle altını gizleme eşlemesini kullanıyorsam böyle bir şeyi nasıl yapabilirim? Haritalama nedeniyle bir fonksiyonum olmadığı için.

    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. Eklentileri kullanmak istiyorum, örneğin, bir kullanıcı bir isteği iptal etmiş gibi, gözlemlenebilirleri geri alabilmek istiyorum, son değere geri dönebilmek istiyorum. Araştırmamdan, bu, düzenlenebilir gibi eklentiler yapan kişiler tarafından başarılmış gibi görünüyor.

    Haritalama kullanıyorsam böyle bir şeyi nasıl kullanırım? Benim görüşümde el ile eşleştirmeye sahip olduğum bir yönteme gerçekten gitmek istemiyorum, her bir MVC viewMode alanını mümkün olduğunca az satır içi javascript istediğim kadar bir KO model alanına eşledim ve bu işin iki katı gibi görünüyor ve bu bu haritayı neden seviyorum.

  5. Bu işi kolaylaştırmak için (haritalama kullanarak) çok fazla KO gücü kaybedeceğimden endişeliyim, ancak diğer yandan manuel haritalamanın çok fazla iş olacağı ve görüşlerimin çok fazla bilgi içermesine neden olacağından endişeliyim ve gelecekte bakımı daha zor hale gelebilir (örneğin, MVC modelindeki bir mülkü kaldırırsam, onu KO görünüm modelinde de taşımam gerekir)


Orijinal Gönderi

Ben asp.net mvc 3 kullanıyorum ve oldukça havalı göründüğü için nakavt araştırıyorum ama asp.net mvc ile nasıl çalıştığını anlamakta zorlanıyorum, özellikle de modelleri görüntüle.

Şu anda benim için böyle bir şey yapıyorum

 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 gibi bazı temel özelliklere sahip bir VM'ye sahip olacaktım ve üzerinde bazı basit doğrulamalar olacak. Vm modeli, gerekirse başka görünüm modellerini de içerebilir.

Daha sonra, kullanıcıya göstermeme yardımcı olması için html yardımcıları kullansaydım, bu Vm'yi Görünüme geçirirdim.

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

Verileri Öğrenci Görünüm Modelleri koleksiyonundan almak için bazı foreach döngülerim veya başka bir şeyim olabilir.

Daha sonra formu gönderdiğimde jquery kullanacak serialize arrayve onu viewmodel'e geri bağlayacak bir controller eylem yöntemine gönderecektim.

Knockout.js ile, artık bunun için görüntüleme modellerine sahip olduğunuz ve gördüğüm tüm örneklerden html yardımcıları kullanmadıkları için her şey farklı.

MVC'nin bu 2 özelliğini knockout.js ile nasıl kullanıyorsunuz?

Bu videoyu buldum ve kısaca ( videonun son birkaç dakikası @ 18:48), temelde ViewModel'de değerler atanan nakavt.js görünüm modeline sahip bir satır içi komut dosyasına sahip olarak görünüm modellerini kullanmanın bir yolunu buldum .

Bunu yapmanın tek yolu bu mu? Benim örneğimde bir görünüm modelleri koleksiyonuna ne dersiniz? Tüm değerleri çıkarıp nakavt olarak atamak için bir foreach döngüsüne veya başka bir şeye sahip olmam gerekir mi?

Html yardımcılarına gelince, video onlar hakkında hiçbir şey söylemiyor.

Pek çok insan bunun hakkında konuşmadığı için kafamı karıştıran 2 alan bunlar ve her örnek sadece sabit kodlanmış bir değer örneği olduğunda, başlangıç ​​değerlerinin ve her şeyin görünüme nasıl ulaştığı konusunda kafamı karıştırıyor.


Düzenle

Darin Dimitrov'un önerdiği şeyi deniyorum ve bu işe yarıyor gibi görünüyor (yine de onun kodunda bazı değişiklikler yapmak zorunda kaldım). Belgeyi neden hazır kullanmak zorunda olduğumdan emin değilim ama bir şekilde her şey onsuz hazır değildi.

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

Çalışması için bir jQuery belgesinin etrafına sarmak zorunda kaldım.

Ben de bu uyarıyı alıyorum. Ne hakkında olduğundan emin değilim.

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

Bu yüzden bir başlangıç ​​noktam var sanırım en azından biraz daha oyun oynadığımda ve bunun nasıl çalıştığını güncelleyeceğim.

Etkileşimli öğreticilerden geçmeye çalışıyorum ancak bunun yerine bir ViewModel kullanıyorum.

Henüz bu parçaların üstesinden nasıl gelineceğinden emin değilim

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

veya

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


Düzenle 2

İlk sorunu çözebildim. İkinci sorun hakkında hiçbir fikrim yok. Yine de. Herhangi bir fikri olan var mı?

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

kontrolör

  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
Başka bir benzer soruyu yanıtlamak için bir blog yazısı yazdım: roysvork.wordpress.com/2012/12/09/… Sorunuza tam olarak cevap vermeyebilir, ancak işlerin nasıl yürüdüğüne dair size iyi bir fikir verir. Bunu çok uzak olmayan bir gelecekte başka bir gönderi ile takip etmeyi umuyorum. Daha fazla bilgiye ihtiyacınız olursa, yazıdaki yorumlarda veya burada bana herhangi bir soru sormaktan çekinmeyin.
kod dışı

Yanıtlar:


180

Sanırım tüm sorularınızı özetledim, bir şeyi kaçırırsam lütfen bana bildirin ( Tüm sorularınızı tek bir yerde özetleyebilseydiniz güzel olurdu =))

Not. ko.editableEklenen eklenti ile uyumluluk

Tam kodu indirin

Knockout.js ile html yardımcılarını nasıl kullanıyorsunuz?

Bu kolay:

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

Nerede:

  • value: CourseIdEğer bağlayıcı olduğunu gösterir valueözelliği inputile kontrol CourseIdmodelinizden mülkiyet ve komut modeli

Sonuç:

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

Çalışması için belge neden hazırdı (daha fazla bilgi için ilk düzenlemeye bakın)

readyModeli serileştirmek için neden olayı kullanmanız gerektiğini henüz anlamıyorum , ancak basitçe gerekli gibi görünüyor (Yine de endişelenmeyin)

Görünüm modellerimle altını gizleme eşlemesini kullanıyorsam böyle bir şeyi nasıl yapabilirim? Haritalama nedeniyle bir fonksiyonum olmadığı için.

Doğru anladıysam KO modeline yeni bir yöntem eklemeniz gerekir, bu da modelleri birleştirmek kolaydır

Daha fazla bilgi için -Farklı kaynaklardan haritalama- bölümünde

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

Aldığınız uyarı hakkında

Uyarı 1 Koşullu derleme kapalı -> @ Html.Raw

Tırnak kullanmalısın

Ko.editable eklentisi ile uyumluluk

Daha karmaşık olacağını düşünmüştüm, ancak entegrasyonun gerçekten kolay olduğu ortaya çıktı, modelinizi düzenlenebilir hale getirmek için aşağıdaki satırı eklemeniz yeterli: (bu durumda sunucudan ve sunucudan karma bir model kullanıyorum istemciye uzantı eklemek ve düzenlenebilir basitçe çalışır ... bu harika):

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

Buradan eklenti tarafından eklenen uzantıları kullanarak bağlamalarınızla oynamanız yeterlidir , örneğin, alanlarımı böyle düzenlemeye başlamak için bir düğmem var ve bu düğmeyle düzenleme işlemini başlatıyorum:

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

Ardından, aşağıdaki kodla tamamla ve iptal et düğmeleri var:

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

Ve son olarak, alanların düzenleme modunda olup olmadığını belirtmek için bir alanım var, bu sadece enable özelliğini bağlamak içindir.

this.isInEditMode = ko.observable(false);

Dizi sorunuz hakkında

Verileri Öğrenci Görünüm Modelleri koleksiyonundan almak için bazı foreach döngülerim veya başka bir şeyim olabilir.

Daha sonra formu gönderirken jquery kullanıp diziyi serileştirir ve onu viewmodel'e geri bağlayacak bir denetleyici eylem yöntemine gönderirim.

Aynı şeyi KO ile de yapabilirsiniz, aşağıdaki örnekte aşağıdaki çıktıyı oluşturacağım:

görüntü açıklamasını buraya girin

Temel olarak burada, HelpersKO kullanılarak oluşturulmuş ve KO ile bağlanmış iki dblClicklisteniz var, bunlar, ateşlendiğinde, seçili öğeyi geçerli listeden kaldırıp diğer listeye eklediğinizde Controller, her birinin içeriğini liste JSON verisi olarak gönderilir ve sunucu modeline yeniden eklenir

Nuggets:

Harici komut dosyaları .

Denetleyici kodu

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

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

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

Kodlar

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

Not: Şu satırları ekledim:

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

Çünkü formu gönderdiğimde alanlarım devre dışı bırakıldı, bu nedenle değerler sunucuya iletilmedi, bu yüzden hile yapmak için birkaç gizli alan ekledim


Hmm çok bilgilendirici. Cevabınızdan ve Pual'ın cevabından, düzenlenebilir gibi eklentilerin nasıl kullanılacağı dışında neredeyse tüm sorularıma yanıt aldım. Umarım birisi bunu nasıl kullanabileceğimi bilir.
chobo2

1
ko.editablesEklentiyle uyumluluk ekledim , güncellenmiş yanıtı kontrol edebilirsiniz veya isterseniz yerel olarak çalıştırmak için tüm projeyi indirebilirsiniz
Jupaol

Yapabildiğim zaman kontrol edeceğim. Çalışması için çok şeyin değiştirilmesi mi gerekiyordu? Merak ediyorum, her eklenti için değişiklik yapmam gerekip gerekmediğini ve sonra kendi sürümümü saklamam gerekip gerekmediğini merak ediyorum.
chobo2


1
Teşekkürler bir grup adam, cevabınızdan birkaç yeni strateji öğrendim. Kudos!
sky-dev

23

ASP.NET MVC görünüm modelinizi bir javascript değişkenine serileştirebilirsiniz:

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

Nakavt belgelerinde geçebileceğiniz birçok örnek var .


1
Evet, sitede sahip oldukları etkileşimli öğreticiyi inceledim ama gerçekten asp.net mvc ile yapacak bir şey görmedim. Onların da bazı eşleme eklentilerine sahip olduklarını görüyorum, ancak bunun nasıl uyduğunu bilmiyorum. Örneğinizde onu nakavt modeline (başka bir komut dosyasında) nasıl bağlarsınız. Gerçekten olabildiğince az satır içi javascript'e sahip olmak istiyorum (olmayan tercih edilir ama sanırım mümkün değil)
chobo2

2
Çözmeye çalıştığınız problem nedir? MVC görünümlerini istiyorsanız ve bunları nasıl kullanacağınızdan memnunsanız, oraya yapışabilirsiniz. Müşteri tarafında veri bağlama ve manipülasyon istiyorsanız, KO harika bir seçimdir. Bu cevabın gösterdiği gibi, KO görünüm modelinizi MVC kodunuzdan oluşturabilirsiniz. VM'yi alır ve json'a serileştirir. Ardından istemcide sonuçları bir javascript görünüm modeliyle eşleyebilirsiniz. Ardından görünüm modelini görünüme bağlayın ve hazırsınız. Anahtar nokta, siz istemedikçe, MVC ve KO'nun herhangi bir şekilde bağlanması gerekmemesidir. Her şey çözmeye çalıştığınız soruna bağlıdır.
John Papa

1
Asp.net mvc ile yapacak bir şey görmemeniz normaldir. Knockout, bir istemci tarafı çerçevesidir. Hangi sunucu yan dilini kullandığınızı bilmiyor ve umursamıyor. Bu 2 çerçeve kesinlikle ayrıştırılmalıdır.
Darin Dimitrov

@JohnPapa - Şimdi bir şeyler yapma şeklimi seviyorum ama aynı zamanda yeni şeyler öğrenmeyi de seviyorum (KO'nun bazı durumlarda çok yararlı olabileceğini görüyorum). KO'nun istemci tarafı senaryosu olduğunu biliyorum ama bana göre bunların birlikte çalıştığını görüyorum. Şu anda görünümlerimi görünüm modellerini ve html yardımcılarını kullanarak oluşturuyorum. Bence KO'nun bununla birlikte çalışması gerekiyor. Örneğin, düzenleme diyaloğunuz olduğunu varsayalım. Bir veri tabanındaki değerleri bu alanlara nasıl tasarlar ve doldurursunuz? Kendi yöntemimi kullanıyor olsaydım, bu bir viewModel'e sahip olan html yardımcılarının bir görünümü olurdu. Görünüm modelini doldurur ve Eylem Yöntemi ile gönderir ve kullanır.
chobo2

1
@ chobo2, knockout bir istemci tarafı çerçevesidir. MVC modelini istemcide uygulamak için istemcideki görünüm modellerini kullanır. Sunucu ayrılmıştır. Ayrıca üzerinde görünüm modelleri de kullanabilirsiniz. Sadece 2 farklı yer. Eğer javascript kullanarak istemcide uygulamak istediğiniz karmaşık bir mantığınız varsa, o zaman nakavt bunu basitleştirebilir. Aksi takdirde, dürüst olmak gerekirse, buna ihtiyacınız yok.
Darin Dimitrov

2

Sunucu eşlemesinden sonra ek hesaplanan özellikleri elde etmek için, istemci tarafında görünüm modellerinizi daha da geliştirmeniz gerekecektir.

Örneğin:

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

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

Dolayısıyla, ham JSON'dan her eşleme yaptığınızda, hesaplanan özellikleri yeniden uygulamanız gerekir.

Ek olarak, eşleme eklentisi, her ileri geri gittiğinizde yeniden oluşturmanın aksine bir görünüm modelini aşamalı olarak güncelleme yeteneği sağlar (içinde ek bir parametre kullanın fromJS):

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

Ve bu, yalnızca eşlenen özellikler modeliniz üzerinde artımlı bir veri güncellemesi yürütür. Haritalama belgelerinde bunun hakkında daha fazla bilgi edinebilirsiniz.

Darin'in FluentJSON paketine verdiği cevabın yorumlarında bahsettiniz . Ben bunun yazarıyım, ancak kullanım durumu ko.mapping'den daha spesifik. Genelde sadece görüntüleme modelleriniz tek yönlü ise (yani sunucu -> istemci) ve daha sonra veriler farklı bir biçimde geri gönderiliyorsa (veya hiç gönderilmiyorsa) kullanırım. Veya javascript görünüm modelinizin sunucu modelinizden büyük ölçüde farklı bir biçimde olması gerekiyorsa.


Hmm o zaman sanırım belki de FluentJSON benim için değil çünkü çoğu zaman görüntü modellerim her iki yöne de gidiyor (genellikle onu json aracılığıyla geri gönderirim ve sonra eylem yöntemi parametresindeki görünüm modeline bağlarım). Düzenlenebilir gibi bahsettiğim eklentileri nasıl kullanabileceğimi biliyor musunuz? Son olarak, haritalama kullanarak ve viewmodelimi kullanmama yerine kullanmaya çalışarak herhangi bir işlevselliği kaybediyor muyum?
chobo2

Hiçbir eklentiyi kullanmadım, bu yüzden emin değilim. Geçmişte yaptığım şey, sadece her değişikliğe abone olmak ve değişime zorlayıp geri almam için bir dizi serileştirilmiş görünüm modeli durumu tutmaktı ( bu soruya bakın ).
Paul Tyng

haritalama sizi herhangi bir işlevsellikten alıkoymaz, sadece hepsinin birlikte güzel bir şekilde oynamasını sağlamak için JS'ye ve JS'den eşlemeyi nasıl işlediğinden emin olmanız ve kurallarına uymanız gerekir.
Paul Tyng

Peki, gönderdiğiniz sorunun kabul edilen yanıtı, temelde eklentinin ne olacağıdır. Gördüğünüz gibi bir görünüm modeli yaptıklarını ve daha sonra yaptıkları işlevlerini kullandıklarını (ko.observableArrayWithUndo ([])) gördüğünüz için kafamı karıştıran şey bu. Haritalama yapıyorsam, bunu nasıl yapacağımı bilmiyorum. Aklıma gelen tek şey, gözlemlenebilirliği geri alan veya her bir mülkü haritalandıran kendi eşlememi yazmaktır (şu anda doğru yapabileceğimden şüphe duyuyorum), ancak daha sonra temelde sunucu tarafı için ve müşteri için bir tane çift görünüm modeline sahibim ve ben sürdürülemez olacağından korktum
chobo2

Ah evet özür dilerim, bu soruya verdiğim cevap hakkında konuşuyordum, özür dilerim doğrudan bağlantılı olmalıydı.
Paul Tyng
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.