2016-05-18 15 views
0

ドロップダウンリストを持つコレクションがあります。 「削除」ボタンのテキストを「X」から「削除」に変更するmouseoverイベントを追加しました。 問題は、特定のボタンだけでなく、すべてのボタンのテキストが変化していることです。マウスオーバーイベントは、特定のボタンだけでなく、リスト内のすべての行のボタンに影響します。

JSFiddlehttp://jsfiddle.net/z22m1798/27/

Javascriptを:

 var CartLine = function(siblings) { 
    var self = this; 

    self.availableFilters = ko.computed(function() { 
     return filters.filter(function(filter) { 
     return !siblings() 
      .filter(function(cartLine) { return cartLine !== self }) 
      .some(function(cartLine) { 
      var currentFilterValue = cartLine.filterValue(); 
      return currentFilterValue && 
       currentFilterValue.name === filter.name; 
      }); 
     }); 
    }); 

    self.filterValue = ko.observable(); 
}; 



var Cart = function() { 
    // Stores an array of filters 
    var self = this; 

    self.btnRemoveTxt = ko.observable("X"); 
    self.lines = ko.observableArray([]); 
    self.lines.push(new CartLine(self.lines))// Put one line in by default 

    self.sortedLines = ko.computed(function() { 
    return self.lines().sort(function(lineA, lineB) { 
     if (lineA.filterValue() && lineA.filterValue().name == "Text") return -1; 
     if (lineB.filterValue() && lineB.filterValue().name == "Text") return 1; 
     return 0; 
    }); 

    }); 

    // Operations 
    self.addFilter = function() { 
    self.lines.push(new CartLine(self.lines)) 
    }; 

    self.removeFilter = function(line) { 
    self.lines.remove(line) 
    }; 

    self.btnRemoveOver = function() { 
     console.log("Yey");/////////////// 
     self.btnRemoveTxt("Remove"); 
    } 
    self.btnRemoveOut = function() { 
     console.log("Yey");/////////////// 
     self.btnRemoveTxt("X"); 
    } 
}; 

// Some of the Knockout examples use this data 
var filters = [{ 
    "filterValues": [{"name": "", }, ], "name": "Text" }, { 
    "filterValues": [{"name": "Yes",}, {"name": "No", }, ],"name": "Choice1" }, { 
    "filterValues": [{"name": "Yes",}, {"name": "No", }, ], "name": "Choice2" }]; 

//Load initial data from server 
var JSONdataFromServer = $("#JSONdataFromServer").val(); 
console.log(JSONdataFromServer); 
    var dataFromServer = ko.utils.parseJson(JSONdataFromServer); 

ko.applyBindings(new Cart()); 

HTML:

<div class='liveExample'> 
<input type="hidden" id="JSONdataFromServer" value='[{ "filterValues": [{"name": "Test"}], "name": "Text" }, { "filterValues": [{"name": "Yes"}, {"name": "No"}], "name": "Choice2" }]'/> 
    <table width='100%'> 
    <tbody data-bind='foreach: sortedLines'> 
     <tr> 
     <td> 
      Choose option: 
     </td> 
     <td> 
      <select data-bind='options: availableFilters, optionsText: "name", value: filterValue'> </select> 
     </td> 
     <td data-bind="with: filterValue"> 
      <!-- ko if: name === "Text" --> 
      <input type="text"> 
      <!-- /ko --> 
      <!-- ko ifnot: name === "Text" --> 
      <select data-bind='options: filterValues, optionsText: "name", value: "name"'> </select>   
      <!-- /ko --> 

     <td> 
<button class="widthFull buttonInput" href='#' data-bind='click: $parent.removeFilter, visible: $parent.lines().length > 1, event: { mouseover: $parent.btnRemoveOver, mouseout: $parent.btnRemoveOut }'><span data-bind="text: $parent.btnRemoveTxt"></span></button> 
     </td> 
     </tr> 
    </tbody> 
    </table> 
    <button data-bind='click: addFilter'>Add Choice</button> 
    <br> 
    <input type="submit"Submit</> 
</div> 

誰かが私をここに助けることができますか? 私はKnockout.jsで新しいです。

ありがとうございます!

答えて

2

btnRemoveTextは、共有プロパティです($parentにあります)。意図したとおりに動作させたい場合は、それぞれをCartLineに追加する必要があります。

しかし、私はこの機能のためにCSSを使用して、単純にお勧めしたい:

.buttonInput::after { 
    content: "X"; 
} 

.buttonInput:hover::after { 
    content: "remove"; 
} 

はるかに簡単なHTMLで:

<button class="widthFull buttonInput" href='#' data-bind=' 
    click: $parent.removeFilter, 
    visible: $parent.lines().length > 1'> 
</button> 

http://jsfiddle.net/8z3agfwc/

完全にするために:あなたの場合do機能をに移動したい3210のviewmodel:

HTML:

<button class="widthFull buttonInput" href='#' data-bind=' 
    click: $parent.removeFilter, 
    visible: $parent.lines().length > 1, 
    event: { 
    mouseover: btnRemoveOver, 
    mouseout: btnRemoveOut 
    }'> 

    <span data-bind="text: btnRemoveTxt"></span> 

</button> 

JS:あなたの説明については

var CartLine = function(siblings) { 
    var self = this; 

    self.btnRemoveTxt = ko.observable("X"); 

    self.btnRemoveOver = function() { 
    self.btnRemoveTxt("Remove"); 
    }; 

    self.btnRemoveOut = function() { 
    self.btnRemoveTxt("X"); 
    }; 

    // etc. 
}; 

http://jsfiddle.net/t4ys35st/

+0

おかげでたくさん!なぜあなたはCSSソリューションを好むのですか? HTMLははっきりしているからでしょうか? – Mike

+0

良い質問です。主に個人的な好みかもしれません。この美的機能には、3つの露出されたビューモデルのプロパティと、行ごとに2つのイベントリスナーが必要です。アクセシビリティと ':: after'の内容に問題があるかどうかはわかりませんが... – user3297291

1

sortedline配列内のすべてのエントリは、基本的に同じプロパティにバインドされます。テキストとして $ parent.btnRemoveTxtを使用しています。ソートされた各行には、独自のbtnRemovetxtプロパティが必要です。

btnRemoveTxtプロパティをsortedlineエントリに追加し、その1つをスパンにバインドします。

clickイベントの場合でも、親レベルで関数を使用できますが、実際のエントリを渡してそのエントリのテキストのみを変更する必要があります。

関連する問題