1

私のアプリケーションでは、ブートストラップとノックアウトを MVC4 に統合しようとしています。ユーザーが項目を選択できる 2 つのドロップダウン コントロールがあり、jQuery を使用してその横のテキスト ボックスに入力します。ViewBag と @foreach ループを使用すると問題なく動作しますが、ノックアウト オブザーバブルを使用しようとすると問題が発生します。

ViewModel のデータがドロップ ダウン コントロールに表示されるのを確認できますが、テキスト ボックスの値は更新されません。使用すべき特別なデータ バインド属性はありますか?

いくつかのコード...

<div class="container">
    <div class="col-sm-7 well">
        <form class="form-inline" action="#" method="get">
            <div class="input-group col-sm-8">
                <input class="form-control" value="" placeholder="Work Section" name="q" type="text">
                <div class="input-group-btn">
                    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Select <span class="caret"></span></button>
                    <ul class="dropdown-menu">
                        <li data-bind="foreach: Names">
                            <a href="#" data-bind="text: Name, value: Name"></a>
                        </li>
                    </ul>
                    <input name="category" class="category" type="hidden">
                </div>
            </div>
            <div class="input-group col-sm-8">
                <input class="form-control item" value="" placeholder="Select a Color" name="color" type="text">
                <div class="input-group-btn">
                    <button type="button" class="btn btn-default dropdown-toggle item" data-toggle="dropdown">Select <span class="caret"></span></button>
                    <ul class="dropdown-menu">
                        @foreach (var item in ViewBag.Colors)
                        {
                            <li>
                                <a href="#">@item</a>
                            </li>
                        }
                    </ul>
                    <input name="category" class="category" type="hidden">
                </div>
            </div>

色が正常に機能しているため、問題は foreach の名前にあります。

これを使用してページ上のコントロールを見つけ、選択したアイテムを取得して入力コントロールに配置します...これが現在、[色] ドロップダウンでのみ機能することを確認しました。

$(function () {
        $(".dropdown-menu li a").click(function () {
            $(this).parents(".input-group").find('.form-control').text($(this).text());
            $(this).parents(".input-group").find('.form-control').val($(this).text());
        });
    });

以下の両方のアプローチを試してみましたが、役に立ちませんでした。最初の応答から始めましょう....

ページ上部のタグに次を配置しました

$(function ViewModel() {
    alert('Here');  // To test if the code generating the model is executed
    this.Names = [{ name: "Person 1", name: "Person 2" }];

    this.selectedName = ko.observable();
    this.clickName = function (name) { this.selectedName = name; }
});

次に、ページの上部に新しいものを配置しました。

<p>Current selection is <span data-bind="text: selectedName"></span></p>

最後に、このコードをブートストラップ ドロップダウンに配置しました。

<ul class="dropdown-menu" data-bind="foreach: Names">
    <li class="dropdown">
        <a href="#" data-bind="text: Name, value: Name, click: clickName(Name)"></a>
    </li>
</ul>

ドロップダウンは空で、div は更新されません。

ここに画像の説明を入力

OK、作成した ViewModel を取得してクリックを統合した後: function() {$root.Name(Name);} 期待どおりに値の更新を確認できるようになりました。

これが私のビューモデルコードです

$(document).ready(function () {
    function ViewModel() {
        var self = this;
        self.Name = ko.observable("");

        var Names = {
            Name: self.Name
        };

        self.Name = ko.observable();
        self.Names = ko.observableArray([{ Name: "Brian" }, { Name: "Jesse" }, {Name: "James"}]);
    }

    var viewModel = new ViewModel();
    ko.applyBindings(viewModel);
});
4

2 に答える 2

1

Bootstrap によって作成されたドロップダウンは、それ自体は実際にはコントロールではなく、単なる派手な CSS です。その結果、Bootstrap ドロップダウンの選択は手動で処理する必要があります。これがノックアウトが本当に役立つところです。

上記のコードに基づいて、単純なjsFiddleを作成しました。

ドロップダウンは次のようになります (foreachバインドの位置は、質問の例とは異なり、ulではなく であることに注意してくださいli):

    <ul class="dropdown-menu" data-bind="foreach: Names">
        <li class="dropdown">
            <a href="#" data-bind="text: Name, value: Name, click: function() {$root.selectedName(Name);}"></a>
        </li>
    </ul>

これは、次のようなビュー モデルを想定しています。

var ViewModel = function() {
    var self = this;

    //Properties
    self.selectedName = ko.observable("NONE");
    self.Names = ko.observableArray([
        { Name:"Name1" },
        { Name:"Name2" },
        { Name:"Name3" },
    ]);    

}

したがって、clickバインディングを使用することで、ユーザーの選択を Knockout ビュー モデルに戻すことができます。もちろん、ビュー内の関数 (function() {$root.selectedName(Name);}ビット) ではなく、メソッドViewModelであることが理想ですが、最初にこのように表示した方がわかりやすいと思いました。

于 2014-03-07T01:44:45.983 に答える
1

ビューモデルが現在次のようになっていると仮定します

function ViewModel() {
  this.Names = [{name: x}, ...];
}

次のように展開する必要があります

function ViewModel() {
  this.Names = [{name: x}, ...];
  this.selectedName = ko.observable();
  this.clickName = function(name) { this.selectedName(name); }
}

次にdata-bind="text: selectedName"、テキスト フィールドとdata-bind="click: clickName(Name)"リンクを配置します。jQuery セレクターが不要なため、データのやり取りを DOM 構造から切り離すことができます。

于 2014-03-07T01:47:37.373 に答える