3

KnockoutJS は初めてです。以下の機能を達成するためのより良い方法があるかどうか知りたいです。

オブジェクトのプロパティは、表の行にテキストとして表示されます。テキストの各スパンを個別にクリックしてテキストボックスを表示し、テキストを編集できます。オブジェクトに関連する他のプロパティは編集可能にならないことに注意してください。一度に編集できるプロパティは 1 つだけです。これを実現するために、KO マッピング中に、実際に各プロパティを、元のプロパティの値を保持する「value」プロパティと、テキスト ボックスの可視性を追跡するために使用する「hasFocus」プロパティの 2 つのプロパティを持つオブジェクトで上書きします。 .

これは、現在どのようにプログラムされているかを示すJSFiddleです。アイテム名と価格をクリックして、テキストボックスが表示されることを確認してください。

さらなる説明

各行が TransactionItem を表すテーブルがあります。

初期状態では、各フィールドはテキストです。クリックすると、テキストが消えてテキストボックスが表示されます。テキスト ボックスがフォーカスを失うと、テキスト ボックスが消え、変更されたテキストが再び表示されます。

次の手順は、これを達成するために私が行ったことを示しています。

  1. KO マッピング プラグイン (この例では「myData」) を使用してサーバーからデータをマッピングします。

    var  myData = [
        {
        TransactionItems: [
            {
            Name: "Item1",
            Price: "1.00"       
            },
            {
            Name: "Item2",
            Price: "2.00"       
            },
            {
            Name: "Item3",
            Price: "3.00"       
            },
        ]},
    ];
    
    var mappingOptions = {          
        'TransactionItems': {
            create: function (options) {
                return new TransactionItem(options.data);
            }
        }   
    }
    var viewModel = {};
    var self = viewModel;
    viewModel.transactions = ko.mapping.fromJS(myData, mappingOptions);
    
    ko.applyBindings(viewModel);
    
  2. TransactionItems コンストラクター関数内で、TransactionItem プロパティ ('name'、'price') の現在の値を取得し、一時変数に格納します。プロパティを新しいオブジェクトで上書きします。これらの新しいオブジェクトには、元のプロパティの「値」と新しい「hasFocus」プロパティの 2 つの値が含まれます。

    //Grab the current values of the properties
    var itemValue = this.Name();
    var priceValue = this.Price();
    
    //Recreate properties as objects, give them a 'hasFocus' property
    this.Name = { value: itemValue, hasFocus: ko.observable(false)};
    this.Price = { value: priceValue, hasFocus: ko.observable(false) };
    

たとえば、'name' プロパティはオブジェクト Name: { value: 'Item1', hasFocus: false } になります。

  1. HTML では、各プロパティの 'hasFocus' をデータ バインドして、テキスト/テキスト ボックスをいつ表示/非表示にするかを制御します。

  2. テキストがクリックされると、「hasFocus」プロパティが true に設定され、テキストが非表示になり、テキスト ボックスが表示されます。

  3. テキスト ボックスがぼやけると、'hasFocus' プロパティが false に設定され、テキスト ボックスが非表示になり、テキストが表示されます。

この機能を実現するためのより良いアプローチがあるかどうかを知りたいです。私は軌道から外れましたか?ありがとう!

コードのより大きなスニペット:

<table>
    <thead>
        <tr>            
            <th>Name</th>
            <th>Price</th>
        </tr>
    </thead>
    <tbody>  
        <!-- ko foreach: transactions -->
            <!-- ko template: { name: 'listItems', foreach: TransactionItems } --> 
            <!-- /ko -->
        <!-- /ko -->
    </tbody>
</table>

<script type="text/html" id="listItems">
    <tr>
        <td>
            <!-- Either show this -->
            <span data-bind="visible: !Name.hasFocus(), 
                             text: Name.value, 
                             click: editItem.bind($data, Name)"></span>

            <!-- Or show this -->
            <input data-bind="visible: Name.hasFocus, 
                              value: Name.value, 
                              hasfocus: Name.hasFocus, 
                              event: { 
                                        focus: editItem.bind($data, Name), 
                                        blur: hideItem.bind($data, Name) 
                                     }" 
            /><!-- end input -->
        </td>
        <td>
            <!-- Either show this -->
            <span data-bind="visible: !Price.hasFocus(), 
                             text: Price.value, click: editItem.bind($data, Price)"></span>

            <!-- Or show this -->
            <input data-bind="visible: Price.hasFocus, 
                              value: Price.value, 
                              hasfocus: Price.hasFocus, 
                              event: { 
                                        focus: editItem.bind($data, Price), 
                                        blur: hideItem.bind($data, Price) 
                                     }" 
            /><!--input end -->
        </td>
    </tr>
</script>

<!-- END OF HTML -->

<script >

function TransactionItem(data) {

    ko.mapping.fromJS(data, {}, this);

    this.editable = ko.observable(false);
    this.hasFocus = ko.observable(false);

    //Grab the current values of the properties
    var itemValue = this.Name();
    var priceValue = this.Price();

    //Recreate properties as objects, give them a 'hasFocus' property
    this.Name = { value: itemValue, hasFocus: ko.observable(false)};
    this.Price = { value: priceValue, hasFocus: ko.observable(false) };

    this.editItem = function (objProperty) {
        this.editable(true);
        objProperty.hasFocus(true);        
    }

    this.hideItem = function (objProperty) {
        this.editable(false);
        objProperty.hasFocus(false);
    }       

}

//MAPPING
var mappingOptions = {

    'TransactionItems': {
        create: function (options) {
            return new TransactionItem(options.data);
        }
    }   
}

//DATA
var  myData = [
    {
    TransactionItems: [
        {
        Name: "Item1",
        Price: "1.00"       
        },
        {
        Name: "Item2",
        Price: "2.00"       
        },
        {
        Name: "Item3",
        Price: "3.00"       
        },
    ]},
        ];

//VIEWMODEL        
var viewModel = {};
var self = viewModel;
viewModel.transactions = ko.mapping.fromJS(myData, mappingOptions);

ko.applyBindings(viewModel);

        </script>
4

1 に答える 1