Domanda

I would like to create knockout viewModel from asp.net MVC model using ko.mapping.fromJS() method but my form didn't populating values.

In view I created script looks like that:

   <script type="text/javascript">
            var tmp = @Html.Raw(Model.ToJson());
            var viewModel = ko.mapping.fromJS(tmp);
            ko.applyBindings(viewModel);
    </script>

@Html.Raw(Model.ToJson() returns value

 {"id":1,
"surveyCode":null,
"title":"Życie",
"description":"Ankieta, w której zadawane będą pytania na temat codziennego życia ",
"dateStart":"2013-12-12T00:00:00",
"dateEnd":"2014-12-30T00:00:00",
"createDate":"2014-01-07T03:23:16.053",
"lastModification":"2014-01-07T03:23:16.053",
"isActive":false,
"questions":[{"id":1,
            "surveyID":1,
            "content":"Co jesz na śniadanie?",
            "tips":"wybierz jedną odpowiedź",
            "questionType":1,
            "isRequired":true,
            "answers":  [{"id":1,
                                "questionID":1,
                                "answerContent":"Jajecznicę",
                                "isOpenAnswer":false},
                         {"id":2,
                                "questionID":1,
                                "answerContent":"Kiełbaski",
                                "isOpenAnswer":false},
                         {"id":3,
                                "questionID":1,
                                "answerContent":"Płatki na mleku",
                                "isOpenAnswer":false},
                         {"id":4,
                                "questionID":1,
                                "answerContent":"Inne",
                                "isOpenAnswer":true}]},
             {"id":2,
             "surveyID":1,
             "content":"Czym się zajmujesz w życiu?",
             "tips":"napisz krótką historię",
             "questionType":3,
             "isRequired":true,
             "answers":[]}]}

but when I want to bind 'title' property to <span> <span data-bind="text:title"></span> it is not working. When I run my app in firefox and turn on firebug script console and set breakpiont to line var tmp = @Html.Raw(Model.ToJson()); returns correct value, press F10 going to next line var viewModel = ko.mapping.fromJS(tmp); and finally press F10 and nothing happen, script not execute next line ko.applyBindings(viewModel);.

And it is my question. Is it possible to mapp my mvc model using knockout mapping plugin automacly? or maybe should I do some manualy staf to map mvc model to knockout viewModel.

I'm looking for answers on this sites: link1 and stackowerflow but maybe I didn't understand this posts.

Edit

my view looks like this:

@using Inżynierka.Extensions
@model Inżynierka.Models.Survey

@{
    ViewBag.Title = "Create";
}


@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>SurveyAnswer</h4>
        <hr />
        @Html.ValidationSummary(true)

        Title: <span data-bind="text:title"></span>


    </div>
}


@section Scripts {
        <script src="../../Scripts/jQuery.tmpl.min.js" type="text/javascript"></script>
        <script src="../../Scripts/knockout-3.0.0.js" type="text/javascript"></script>
        <script src="../../Scripts/knockout.validation.js"></script>
        <script src="../../Scripts/knockout.knockout.mapping-latest.js"></script>
        <script type="text/javascript">
            var tmp = @Html.Raw(Model.ToJson());
            var viewModel = ko.mapping.fromJS(tmp);
            ko.applyBindings(viewModel);
        </script>
    @Scripts.Render("~/bundles/jqueryval")
}

Edit 2

It is html sourse of my page:

<!DOCTYPE html>
<html>
<head>
    <script type='text/javascript' src='http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js'></script>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Create</title>
    <link href="/Content/bootstrap.css" rel="stylesheet"/>
<link href="/Content/site.css" rel="stylesheet"/>

    <script src="/Scripts/modernizr-2.6.2.js"></script>


</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/">Ankietyy</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a href="/Surveys">Moje Ankiety</a></li>
                    <li><a href="/">Strona Gł&#243;wna</a></li>
                    <li><a href="/Home/About">O Projekcie</a></li>
                    <li><a href="/Home/Contact">Kontakt</a></li>
                </ul>
                <form action="/Account/LogOff" class="navbar-right" id="logoutForm" method="post"><input name="__RequestVerificationToken" type="hidden" value="fWDZFmyGqJyU3ATUf2IbHDdkbo22bzObUMwUfxfqwXIiqGvRYzMhApWS3I5GkkHnZD7ieDxLfh84s2-prLDtSGeE6_D7p7cT-fmQBszeM06p-fZ7RzhOPn0P8EDftLRwT8YQA8t2U56dlLX_lx3G4Q2" />    <ul class="nav navbar-nav navbar-right">
        <li>
            <a href="/Account/Manage" title="Manage">Witaj Bartek!</a>
        </li>
        <li><a href="javascript:document.getElementById('logoutForm').submit()">Wyloguj się</a></li>
    </ul>
</form>
            </div>
        </div>
    </div>
    <div class="container body-content">




<form action="/SurveyAnswer/CompleteSurvey/1" method="post"><input name="__RequestVerificationToken" type="hidden" value="KOALGZbw0WhFlBV4LHx530Oen59aBWF62b6s58GIUikx3A62uhcAi3-74auJpLtI4fYj9kmcPjlgNu1TeuNrYukpFlll1cGCOIcjjewtFou4M9C3_bHDFk7UoZk_tKpw7SxcXa3UbgwIj4ZhCRM6_g2" />    <div class="form-horizontal">
        <h4>SurveyAnswer</h4>
        <hr />


        Title: <span data-bind="text:title"></span>


    </div>
</form><script type="text/javascript">
            var tmp = {"id":1,"surveyCode":null,"title":"Życie","description":"Ankieta, w której zadawane będą pytania na temat codziennego życia ","dateStart":"2013-12-12T00:00:00","dateEnd":"2014-12-30T00:00:00","createDate":"2014-01-07T03:23:16.053","lastModification":"2014-01-07T03:23:16.053","isActive":false,"questions":[{"id":1,"surveyID":1,"content":"Co jesz na śniadanie?","tips":"wybierz jedną odpowiedź","questionType":1,"isRequired":true,"answers":[{"id":1,"questionID":1,"answerContent":"Jajecznicę","isOpenAnswer":false},{"id":2,"questionID":1,"answerContent":"Kiełbaski","isOpenAnswer":false},{"id":3,"questionID":1,"answerContent":"Płatki na mleku","isOpenAnswer":false},{"id":4,"questionID":1,"answerContent":"Inne","isOpenAnswer":true}]},{"id":2,"surveyID":1,"content":"Czym się zajmujesz w życiu?","tips":"napisz krótką historię","questionType":3,"isRequired":true,"answers":[]},{"id":14,"surveyID":1,"content":"Pytanie końcowe","tips":"napisz","questionType":1,"isRequired":true,"answers":[{"id":9,"questionID":14,"answerContent":"test","isOpenAnswer":false},{"id":10,"questionID":14,"answerContent":"test2","isOpenAnswer":false},{"id":11,"questionID":14,"answerContent":"test3","isOpenAnswer":false}]}],"surveyAnswers":[],"codeForUsers":[]};
            var viewModel = ko.mapping.fromJS(tmp);
            ko.applyBindings(viewModel);
</script>



        <hr />
        <footer>
            <p>&copy; 2014 - My ASP.NET Application</p>
        </footer>
    </div>

    <script src="/Scripts/jquery-2.0.3.js"></script>

    <script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/respond.js"></script>


    <script src="../../Scripts/jQuery.tmpl.min.js" type="text/javascript"></script>
    <script src="../../Scripts/knockout-3.0.0.js" type="text/javascript"></script>
    <script src="../../Scripts/knockout.validation.js"></script>
    <script src="../../Scripts/knockout.mapping-latest.js"></script>

    <script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>



<!-- Visual Studio Browser Link -->
<script type="application/json" id="__browserLink_initializationData">
    {"appName":"Firefox","requestId":"9f8e517696004299808eb3caccb0e136"}
</script>
<script type="text/javascript" src="http://localhost:11897/dc47e85290da49019e6425ddd16f962a/browserLink" async="async"></script>
<!-- End Browser Link -->

</body>
</html>

Answer for my issue

View should looks like that:

@using Inżynierka.Extensions
@model Inżynierka.Models.Survey

@{
    ViewBag.Title = "Create";
}


@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>SurveyAnswer</h4>
        <hr />
        @Html.ValidationSummary(true)

        Title: <span data-bind="text:title"></span>


    </div>
}



@section Scripts {
    <script src="../../Scripts/knockout-3.0.0.js" type="text/javascript"></script>
    <script src="../../Scripts/knockout.mapping-latest.js"></script>
    <script type="text/javascript">
            var tmp = @Html.Raw(Model.ToJson());
            var viewModel = ko.mapping.fromJS(tmp);
            ko.applyBindings(viewModel);
    </script>

    @Scripts.Render("~/bundles/jqueryval")
}

Thanks everyone for replies, specially for @VolodymyrBilyachat whose advices were most relevant.

È stato utile?

Soluzione

Well after you post source, then other idea what it could is that some scripts are conflicting, try to remove scripts and left only knockout ones

Altri suggerimenti

Wrap your knockout view model in a document.ready function

<script type="text/javascript">
    $document.ready(function() {
            var tmp = @Html.Raw(Model.ToJson());
            var viewModel = ko.mapping.fromJS(tmp);
            ko.applyBindings(viewModel);});
    </script>

Also note that your viewModel isn't a true view model at that point so consider using a view model that contains the ko.observable property 'myData' or something to hold your data and then applying bindings

For complex models I don't believe mappings and simply, I'm parsing json on my own and populate model via loops, ifs and so on. I think, this isn't the worst solution, because debugging and fixing data becomes simplier.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top