admin管理员组

文章数量:1278985

I have a knockout app and within it I have a function which shows/hides elements on the page depending on the selected option. The button that has been selected to activate a particular toggle will have an 'active' class so that it 'stands out' from the others and is clearly visible that that's the selected option. My problem is that I've created a knockout function to toggle the active class but it's triggering the active state on all of the buttons rather than the selected button and I'm not sure why?

var viewModel = function(){
    var self = this;
    self.isActive = ko.observable(false);
    self.toggleActive = function(data, event){
        self.isActive(!self.isActive()); //toggle the isActive value between true/false
    }
}

<button data-bind="click: toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>
<button data-bind="click: toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>
<button data-bind="click: toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>

Fiddle: /

I have a knockout app and within it I have a function which shows/hides elements on the page depending on the selected option. The button that has been selected to activate a particular toggle will have an 'active' class so that it 'stands out' from the others and is clearly visible that that's the selected option. My problem is that I've created a knockout function to toggle the active class but it's triggering the active state on all of the buttons rather than the selected button and I'm not sure why?

var viewModel = function(){
    var self = this;
    self.isActive = ko.observable(false);
    self.toggleActive = function(data, event){
        self.isActive(!self.isActive()); //toggle the isActive value between true/false
    }
}

<button data-bind="click: toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>
<button data-bind="click: toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>
<button data-bind="click: toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>

Fiddle: http://jsfiddle/amMup/5/

Share Improve this question edited Apr 30, 2014 at 10:47 leaksterrr asked Apr 30, 2014 at 10:40 leaksterrrleaksterrr 4,1677 gold badges36 silver badges68 bronze badges 2
  • Since you've tagged jQuery, you might want to consider using jQuery's toggleClass function: api.jquery./toggleClass – Luketep Commented Apr 30, 2014 at 10:42
  • 1 That was a mistake; swiftly fixed. It's best not to mix knockout functions w/ jquery functions – leaksterrr Commented Apr 30, 2014 at 10:43
Add a ment  | 

3 Answers 3

Reset to default 7

You only have one viewmodel for all three buttons. That means you only have a single "isActive" flag that all buttons are bound to.

Instead, use an array of items and a foreach loop to render each one. Here's a tweaked version of your view model:

var viewModel = function(){
    var self = this;
    self.items = [
        { isActive: ko.observable(false) },
        { isActive: ko.observable(false) },
        { isActive: ko.observable(false) }
        ];
    self.toggleActive = function(data, event){
        data.isActive(!data.isActive());//toggle the isActive value between true/false
    }
}

var myModel = new viewModel();

ko.applyBindings(myModel);

And the HTML is simplified:

<div data-bind="foreach: items">
    <button data-bind="click: $parent.toggleActive, css : {'activeStyle' : isActive}">Toggle Active</button>
</div>

Note the use of $parent to access the parent's binding context. When you're inside a foreach loop, the binding context is the individual item pulled from the foreach loop. By accessing $parent you "reach up" to the object that contains the items property -- which, in your case, is the viewmodel where the toggleActive exists.

Here's an updated fiddle: http://jsfiddle/psteele/amMup/6/

This is because you have them all bound to the same observable.

http://jsfiddle/Kohan/fdzqJ/

Js

var viewModel = function(){
    var self = this;
    self.isActive1 = ko.observable(false);
    self.isActive2 = ko.observable(false);
    self.isActive3 = ko.observable(false);

    self.toggleActive = function(data){
        data(!data());
    }
}

var myModel = new viewModel();

ko.applyBindings(myModel);

HTML

<button data-bind="click: function(){toggleActive(isActive1)}, css : {'activeStyle' : isActive1}">Toggle Active</button>
<button data-bind="click: function(){toggleActive(isActive2)}, css : {'activeStyle' : isActive2}">Toggle Active</button>
<button data-bind="click: function(){toggleActive(isActive3)}, css : {'activeStyle' : isActive3}">Toggle Active</button>

Another way:

<button data-bind="click: function(){setActive('1')}, css:  buttonActive() == '1' ? 'active' : '' ">Toggle Active</button>

var viewModel = function(){
    var self = this;
    self.buttonActive = ko.observable(false);
    self.buttonActive = function(index){
        self.buttonActive(index);
    }
}

var myModel = new viewModel();

ko.applyBindings(myModel);

本文标签: javascriptKnockout toggle active class on clickStack Overflow