Need to pass initial viewmodel data from ASP.NET M

2019-03-13 23:30发布

问题:

I was looking at the Contacts editor sample on the knockout.js website:

http://knockoutjs.com/examples/contactsEditor.html

The sample works perfectly, but I needed to make two changes to it:

  • Pass the initial data from ASP.NET MVC 3 controller action method. Here is the code from the server:

Classes

public class Phone
{
    public string Type { get; set; }
    public string Number { get; set; }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public List<Phone> Phones { get; set; }
}

Sample Controller side code

       List<Phone> phoneList = new List<Phone>();

        Person p1 = new Person()
        {
            FirstName = "Abc",
            LastName = "Xyz"
        };

        Phone phone1 = new Phone()
        {
            Type = "Home",
            Number = "1111111111"
        };
        Phone phone2 = new Phone()
        {
            Type = "Mobile",
            Number = "1111111112"
        };

        phoneList.Add(phone1);
        phoneList.Add(phone2);

        p1.Phones = phoneList;

        List<Phone> phoneList2 = new List<Phone>();

        Person p2 = new Person()
        {
            FirstName = "Pqr",
            LastName = "Stu"
        };

        Phone phone3 = new Phone()
        {
            Type = "Home",
            Number = "1111111113"
        };
        Phone phone4 = new Phone()
        {
            Type = "Mobile",
            Number = "1111111114"
        };

        phoneList2.Add(phone3);
        phoneList2.Add(phone4);

        p2.Phones = phoneList2;

        people.Add(p1);
        people.Add(p2);

        ViewBag.InitialData = Json(people, JsonRequestBehavior.AllowGet);
  • Apart from rows of contacts that are part of the ViewModel, I also need to pass some data (e.g. ContactListName and ContactListOwner) that doesn't belong to the rows of contacts but to the ViewModel itself. These properties will be shown outside the grid of contacts.

I would really appreciate if someone can help me with this.

回答1:

The Json method you are calling in your controller is meant to return a JsonResult it does not create a JSON string. You would use this method to return json from an ajax call.

To return a JSON string to a view use something like this.

JavaScriptSerializer serializer = new JavaScriptSerializer();
ViewBag.InitialData = serializer.Serialize(people); 

Then in your view code

<script>
    var initialData = '@Html.Raw(ViewBag.InitialData)';
    ....
</script>

To answer your second question. In order to pass global list data such as this simply define a new class ContactsList e.g

public class ContactsList 
{
    public string Name { get;set; }
    public string Owner { get;set; }
    public IList<People> People { get;set; }
}

Populate this and pass this to the JavascriptSerializer instead. You will obviously need to adjust your js ContactsModel accordingly.

EDIT

Here's a jsfiddle that demonstrates the changes needed.

http://jsfiddle.net/madcapnmckay/jRjwU/

Hope this helps.



回答2:

You could also use your model instead of the ViewBag:

Controller:

        public ActionResult Index()
        {
            var data= GetYourDataFromSomewhere();

            return View(data);
         }

View:

@model IEnumerable<ModelName>

....

<script type="text/javascript">
    $(document).ready(function () {

        var dataForKO = new KOViewModel(@Html.Raw(Json.Encode(Model)));


回答3:

as far as the first part of the question is concerned you can try

<script>
    var initialData = '@Html.Raw(ViewBag.InitialData)'; //get the raw json
    var parsedJSON = $.parseJSON(initialData); //parse the json client side
    ko.applyBindings(new ContactsModel(parsedJSON));

</script>

the second part i really haven't understood...