通过javascript函数更改敲除foreach中特定项目的背景图片

时间:2018-12-24 01:00:20

标签: indexing knockout.js foreach

我正在使用淘汰赛foreach显示游戏板列表。游戏板上的类/标识为“ gameBoard”。

我希望能够仅更改检测到得分变化的游戏板的背景图像。

问题是,当foreach生成板时,它们都获得相同的类/ ID名称,因此无法严格引用该板。一旦homeTeamScore.observables订阅方法被触发,更改背景可能是最简单的选择,并且可以设置,但我不知道如何引用该板。

<div data-bind="foreach: collection">
<div id="gameBoardTemplate" type="text/html">
    <div id="gameBoard" data-bind="visible: IsVisible">
        <div class="gameHeader">
            <h1 class="gameNameHeader" data-bind="text:'Game ' + GameChannel()"></h1>
        </div> <!-- End of game header -->
        .............. etc

上面的第3行是我要更改其背景的div

下面是一些基因剔除和javascript内容的副本。

var Board = function (gameChannel, homeTeamImage, homeTeamName, homeBeerPrice, homeTeamArrow, homeBeer, homeBeerAdjustedPrice, homeTeamScore, awayTeamArrow, awayBeerPrice, awayTeamName, awayBeerAdjustedPrice, awayBeer, awayTeamImage, awayTeamScore, isVisible) {
    this.GameChannel = ko.observable(gameChannel);
    this.HomeTeamImage = ko.observable(homeTeamImage);
    this.HomeTeamName = ko.observable(homeTeamName);
    this.HomeBeerPrice = ko.observable(homeBeerPrice);
    this.HomeTeamArrow = ko.observable(homeTeamArrow);
    this.HomeBeer = ko.observable(homeBeer);
    this.HomeBeerAdjustedPrice = ko.observable(homeBeerAdjustedPrice);
    this.HomeTeamScore = ko.observable(homeTeamScore);
    this.AwayTeamArrow = ko.observable(awayTeamArrow);
    this.AwayBeerPrice = ko.observable(awayBeerPrice);
    this.AwayTeamName = ko.observable(awayTeamName);
    this.AwayBeerAdjustedPrice = ko.observable(awayBeerAdjustedPrice);
    this.AwayBeer = ko.observable(awayBeer);
    this.AwayTeamImage = ko.observable(awayTeamImage);
    this.AwayTeamScore = ko.observable(awayTeamScore);
    this.IsVisible = ko.observable(isVisible);

    this.FullScore = ko.computed(function () { return this.HomeTeamScore() + " | " + this.AwayTeamScore(); }, this);

    this.HomeTeamScore.subscribeChanged(function (newScore, oldScore) {
        if (oldScore.localeCompare("") == -1) {
            showTouchdownAnimation();
        }
    });

    this.AwayTeamScore.subscribeChanged(function (newScore, oldScore) {
        if (oldScore.localeCompare("") == -1) {
            showTouchdownAnimation();
        }
    }); 
}

//This gets populated through an ajax call so its not always blank. Assume its always populated correctly
var viewModel = {
// Game board placeholders
collection: [
    new Board("0", "", "", "", "", "", "", "", "", "", "", "", "", "", "",false),
    new Board("0", "", "", "", "", "", "", "", "", "", "", "", "", "", "",false)
]
};


ko.applyBindings(viewModel);

我想引用触发HomeTeamScore()订阅方法并更改背景的确切电路板,但是当所有的电路板在foreach循环迭代并创建它们时都得到相同的类和ID名称时,该怎么办呢?

谢谢!

2 个答案:

答案 0 :(得分:0)

您可以使用css绑定简单地在主场得分或客场得分> 0时应用CSS类:

<div data-bind="foreach: collection">
<div id="gameBoardTemplate" type="text/html">
    <div id="gameBoard" data-bind="visible: IsVisible, css: { 'HomeTeamScored': HomeTeamScore() > 0, 'AwayTeamScored': AwayTeamScore() > 0 }">

(我确定您知道元素ID的唯一性,因此您可能应该在此处将ID更改为类。)

另一种方法是使背景图像成为您的Board模型的属性,并利用模板中的style绑定。然后,您可以在得分改变时执行的功能中对其进行操作。这样(为简便起见,删除了无关的代码):

var Board = function (gameChannel, homeTeamImage, homeTeamName, homeBeerPrice, homeTeamArrow, homeBeer, homeBeerAdjustedPrice, homeTeamScore, awayTeamArrow, awayBeerPrice, awayTeamName, awayBeerAdjustedPrice, awayBeer, awayTeamImage, awayTeamScore, isVisible) {
    var self = this;
    ...
    this.BGImage = ko.observable(null);

    this.HomeTeamScore.subscribeChanged(function (newScore, oldScore) {
        if (oldScore.localeCompare("") == -1) {
            showTouchdownAnimation();
            self.BGImage("Huzzah.jpg");
        }
    });
}

模板:

<div data-bind="foreach: collection">
    <div class="gameBoardTemplate" type="text/html">
        <div class="gameBoard" data-bind="visible: IsVisible, style: { backgroudImage: BGImage }">

答案 1 :(得分:0)

您所需要的只是对this的引用,这样就只影响相应的视图模型。因此,我创建了self变量以在您的订阅函数中引用this

现在,您可以调用相关视图模型的isVisible观察对象并将其值更改为true

为清楚起见,我制作了一个摘要。顺便说一句,我将'gameBoard'更改为类而不是ID。 ID必须是唯一的,并且对于foreach不能正确使用。

ko.subscribable.fn.subscribeChanged = function(callback, context) {
    var savedValue = this.peek();
    return this.subscribe(function(latestValue) {
        var oldValue = savedValue;
        savedValue = latestValue;
        callback.call(context, latestValue, oldValue);
    });
};

var Board = function (gameChannel, homeTeamImage, homeTeamName, homeBeerPrice, homeTeamArrow, homeBeer, homeBeerAdjustedPrice, homeTeamScore, awayTeamArrow, awayBeerPrice, awayTeamName, awayBeerAdjustedPrice, awayBeer, awayTeamImage, awayTeamScore, isVisible) {
    var self = this;
    this.GameChannel = ko.observable(gameChannel);
    this.HomeTeamImage = ko.observable(homeTeamImage);
    this.HomeTeamName = ko.observable(homeTeamName);
    this.HomeBeerPrice = ko.observable(homeBeerPrice);
    this.HomeTeamArrow = ko.observable(homeTeamArrow);
    this.HomeBeer = ko.observable(homeBeer);
    this.HomeBeerAdjustedPrice = ko.observable(homeBeerAdjustedPrice);
    this.HomeTeamScore = ko.observable(homeTeamScore);
    this.AwayTeamArrow = ko.observable(awayTeamArrow);
    this.AwayBeerPrice = ko.observable(awayBeerPrice);
    this.AwayTeamName = ko.observable(awayTeamName);
    this.AwayBeerAdjustedPrice = ko.observable(awayBeerAdjustedPrice);
    this.AwayBeer = ko.observable(awayBeer);
    this.AwayTeamImage = ko.observable(awayTeamImage);
    this.AwayTeamScore = ko.observable(awayTeamScore);
    this.IsVisible = ko.observable(isVisible);

    this.FullScore = ko.computed(function () { return this.HomeTeamScore() + " | " + this.AwayTeamScore(); }, this);

    this.HomeTeamScore.subscribeChanged(function (newScore, oldScore) {
        //if (oldScore.localeCompare("") == -1) {
            //showTouchdownAnimation();
            self.IsVisible(true);
            setTimeout(function(){
              self.IsVisible(false);
            },3000);
        //}
    });

    this.AwayTeamScore.subscribeChanged(function (newScore, oldScore) {
        //if (oldScore.localeCompare("") == -1) {
            //showTouchdownAnimation();
            self.IsVisible(true);
            setTimeout(function(){
              self.IsVisible(false);
            },3000);

       // }
    }); 
}

//This gets populated through an ajax call so its not always blank. Assume its always populated correctly
var viewModel = {
// Game board placeholders
collection: [
    new Board("0", "", "", "", "", "", "", "", "", "", "", "", "", "", "",false),
    new Board("1", "", "", "", "", "", "", "", "", "", "", "", "", "", "",false)
]
};


ko.applyBindings(viewModel);
.gameBoard {
  width: 200px;
  height: 200px;
  display: block;
  position: relative;
}

.gameBoard::after {
  content: "";
  background: url('http://ayay.co.uk/backgrounds/sports/american_football/38-1024x768.jpg');
  background-repeat: no-repeat;
  background-size: 200px 200px;
  opacity: 0.5;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  position: absolute;
  z-index: -1;   
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>


<div data-bind="foreach: collection">
<div id="gameBoardTemplate" type="text/html">
    <div class="gameBoard" data-bind="visible: IsVisible">
        <div class="gameHeader">
            <h1 class="gameNameHeader" data-bind="text:'Game ' + GameChannel()"></h1>
        </div>
    </div>
    <div>
      <input data-bind="value: HomeTeamScore"/>
      <br>
      <input data-bind="value: AwayTeamScore"/>
    </div>
</div>
<br><br>
</div>