0

私は C# MVC 開発者であり、クライアント側の JavaScript をイベント ハンドラーのもつれからより組織化されたシステムに進化させたいと考えているため、knockoutjs を検討し始めています。最初は見栄えがよく、本番環境にどのように導入するかについてのアイデアがすぐに形成されました。私はいくつかの基本原則を試しましたが、それらはすべて問題なくうまく機能しました。もう少し複雑なこと (私が取り組んでいるプロジェクトに固有のもの) を試してみたいと思っていますが、うまくいきません。

これの他の例を検索しようとしましたが、実際に一致するものは見つかりませんでした。

私がやりたいことは、オブジェクトのリストをクライアント側にバインドすることです。この例では、ページに表示している人のリストを使用しており、ajax リクエストでページ上のすべての人を更新したいと考えています (この例は純粋にテスト用に作成されたものですが、原則は私です後)。

ノックアウトjsマッピングプラグインを使用してモデルマッピングを行っています

私のC#コード

 public class HomeController : Controller
    {
        public ActionResult Index()
        {
            List<Person> people = new List<Person>()
            {
               new Person()
                {
                    FirstName = "Neil",
                    LastName = "Diamond"
                },
                new Person()
                {
                    FirstName = "Bob",
                    LastName = "Seager"
                },
                new Person()
                {
                    FirstName = "Tom",
                    LastName = "Jones"
                }
            };

            return View(people);
        }

        public JsonResult UpdateNames()
        {
            Random r = new Random();
            var num = r.Next(1, 100);
            List<Person> people = new List<Person>()
            {
               new Person()
                {
                    FirstName = string.Concat("Neil", num.ToString()),
                    LastName = string.Concat("Diamond", num.ToString())
                },
                new Person()
                {
                    FirstName = string.Concat("Bob", num.ToString()),
                    LastName = string.Concat("Seager", num.ToString())
                },
                new Person()
                {
                    FirstName = string.Concat("Tom", num.ToString()),
                    LastName = string.Concat("Jones", num.ToString())
                }
            };
            return Json(people, JsonRequestBehavior.AllowGet);
        }
    }

私の見解

@model List<TestingKnockout.Models.Person>

@{
    ViewBag.Title = "Home Page";
}

@for (int i = 0; i < Model.Count; i++)
{
    <p>Firstname: <strong data-bind="text: [@i].FirstName"></strong></p>
    <p>Lastname: <strong data-bind="text: [@i].LastName"></strong></p>
    <hr />
}

@section scripts
{
    <script src="~/Scripts/knockout-2.1.0.js"></script>
    <script src="~/Scripts/knockout.mapping.js"></script>
    <script type="text/javascript">
        var viewModel = {};
        $.ajax({
            url: "/Home/UpdateNames",
            cache: false,
            success: function (data) {
                viewModel = ko.mapping.fromJS(data);
                ko.applyBindings(viewModel);
            }
        });

        setInterval(function () {
            $.ajax(
                {
                    url: "/Home/UpdateNames",
                    cache: false,
                    success: function (data) {
                        ko.mapping.fromJS(data, viewModel);
                    }
                });
        }, 5000);
    </script>
}

何か助けをいただければ幸いです。または、明らかなことを見逃している場合、またはこの質問が前に出てきた場合は、正しい方向に向けてください。

よろしく

編集

Tomas と Rodney からの両方の回答で、ノックアウトの振る舞いを誤って想定していたようです。ノックアウトは、モデル全体を JSON として開始し、そこから更新する必要があります。HTML を初期データでレンダリングし、ノックアウトして更新を処理することを望んでいましたが、私のアプローチは間違っていたと思います。Tomas の HTML と Rodney のコードを参考に (json のシリアライゼーションと観察可能な人にマイナーな変更を加えました)、ビューのコードを次のように変更しました。

@model List<TestingKnockout.Models.Person>

@{
    ViewBag.Title = "Home Page";
}

<div data-bind="foreach: people">
    <p>Firstname: <strong data-bind="text: FirstName"></strong></p>
    <p>Lastname: <strong data-bind="text: LastName"></strong></p>
    <hr />
</div>
@section scripts
{
    <script src="~/Scripts/knockout-2.1.0.js"></script>
    <script src="~/Scripts/knockout.mapping.js"></script>
    <script type="text/javascript">
        var viewModel = {
            people:  ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)))    
            };
        ko.applyBindings(viewModel);    

        setInterval(function () {
            $.ajax(
                {
                    url: "/Home/UpdateNames",
                    cache: false,
                    success: function (data) {
                        ko.mapping.fromJS(data, viewModel.people);
                    }
                });
        }, 5000);
    </script>
}

トーマスとロドニーの両方に答えたいと思います。どちらかを選ばなければならないのは、Rodney が一番助けてくれたと思うので、Tomas に申し訳ありません。

4

2 に答える 2

3

Tomas の回答の HTML を使用します。

最初の C# モデルを javascript リストにシリアライズする必要があります。これを行う一般的な方法は、JSON.NET ライブラリを使用することです。

この C# コードをビューの先頭に追加します

@using Newtonsoft.Json
@{
    var jsPeople = Html.Raw(JsonConvert.SerializeObject(Model));
}

すべての JavaScript を次のものに置き換えます。

var viewModel = { people: ko.observable([]) };
viewModel.people(ko.mapping.fromJS(@jsPeople));

setInterval(function () {
    $.ajax(
    {
        url: "/Home/UpdateNames",
        cache: false,
        success: function (data) {
            viewModel.people(ko.mapping.fromJS(data));
        }
    });
}, 5000);

$(document).ready(function(){
    ko.applyBindings(viewModel);
});

ああ、ここで jquery を使用して、ドキュメントの準備ができたときに applyBindings を実行したことを言及する必要があります。

于 2013-05-30T23:58:00.813 に答える