Get MVC Person Model book list within knockout mod

2019-07-03 22:32发布

What is the best practice to get MVC Model parameters within knockout Model?

1) If you need to get just one parameter, you can use the following to set up knockout view model property:

this.firstName = @Model.FirstName;

2) If you have a bunch of properties wihtin a model, you can do the following:

var modelData = function () { return @Html.Raw(Json.Encode(Model)); }();

and then later use

this.firstName = modelData.FirstName;
this.lastName = modelData.LastName;
this.phoneNumber = modelData.PhoneNumber; 
etc.

3) What if you have some Collection within Person model. What is the best way to get the collection out of the person model?

For example, Person has FirstName, LastName, PhoneNumber etc. and has a List of Books (each book has tile, author and other properties).

I believe you can use seomething like this:

var booksJSON = @Html.Raw(Json.Encode(Model.Books));

and then in the knockout Person model use:

self.books = ko.observableArray(booksJSON);

This gives only Books.

But what if I want to get all information about Person (Books, including FirstName, LastName, Phone and a bunch of properties), what is the best way to do this? Can I somehow use Json.Encode for the whole Person model and then get out of there everything, including Person.Books or should I split it into multiple Json.Encode-s??

2条回答
forever°为你锁心
2楼-- · 2019-07-03 23:01

If you want to make a simple (one-way) binding, this will do

var PersonViewModel = {};
$(function () {
    var personJSON = @Html.Raw(Json.Encode(Model));
    PersonViewModel = ko.observable(personJSON);
    ko.applyBindings(PersonViewModel, $("#person-container").get(0));
});

But if you want a two-way binding, ie, you wanna post back changes to the existing array back to server, you wanna make all properties in the object array ko.observable. That's because, as per knockoutjs documentation,

Simply putting an object into an observableArray doesn’t make all of that object’s properties themselves observable. Of course, you can make those properties observable if you wish, but that’s an independent choice. An observableArray just tracks which objects it holds, and notifies listeners when objects are added or removed.

To make each object properties in the array ko.observable, we can use this generic function.

function MakeArrayKoObservableObjectArray(arr) {
    var observableArr = [];
    for (var i = 0; i < arr.length; i++) {
        var observableObj = {}, obj = arr[i];
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                observableObj[prop] = ko.observable(obj[prop]);
            }
        }
        observableArr.push(observableObj);
    }
    return observableArr;
}

Now we can use the function like this.

var personJSON = @Html.Raw(Json.Encode(Model));
personJSON.Books = MakeArrayKoObservableObjectArray(personJSON.Books);
PersonViewModel = ko.observable(personJSON);
查看更多
ら.Afraid
3楼-- · 2019-07-03 23:15

All data what you need should be in your C# Model. Then in knockout viewModel you should parse this data. For example:

C#

public class Person
{
    public int Id {get;set;}
    public string FirstName {get;set;}
    public string LastName {get;set;}
    public List<Book> Books {get;set}
} 

public class Book
{
    public int Id {get;set;}
    public string Name {get;set;}        
}

Html, you should convert your C# model to json:

function (ko, ViewModel) {
     ko.applyBindings(new ViewModel(@Html.Raw(Model.ToJson())), document.getElementById('Container'));
});

Knockout viewModel:

function ViewModel(model) {
    var self = this;

    self.FirstName = ko.observable(model.FirstName);
    self.LastName = ko.observable(model.LastName);
    self.Books = ko.observableArray(model.Books); 
}
查看更多
登录 后发表回答