Изменить фоновое изображение определенного элемента в нокауте foreach с помощью функции javascript - PullRequest
0 голосов
/ 24 декабря 2018

Я использую нокаут foreach для отображения списка игровых досок.Игровое поле имеет класс / идентификатор «gameBoard».

Я хочу иметь возможность изменять фоновое изображение только игрового поля, которое обнаруживает изменение счета.

Проблема в том, когда foreachгенерирует доски, все они получают одно и то же имя класса / идентификатора, поэтому нет возможности строго ссылаться на эту отдельную доску. Изменение фона после запуска метода подписки 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 выполняет итерацию и создает их.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Все, что вам нужно, это ссылка на this, так что затрагивается только соответствующая модель вида.Поэтому я создал переменную self для ссылки на this внутри вашей функции подписки.

Теперь вы можете вызвать наблюдаемую isVisible соответствующей модели представления и изменить ее значение на true.

Я сделал фрагмент для ясности.Кстати, я изменил «gameBoard» на класс вместо идентификатора.Идентификаторы должны быть уникальными и не будут работать правильно для 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>
0 голосов
/ 24 декабря 2018

Вы можете просто применить класс 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 }">

(я уверен, что вы знаете, что идентификатор элемента долженбыть уникальным, поэтому вам, вероятно, следует сменить идентификаторы на классы.)

Другой способ - сделать фоновое изображение свойством модели 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 }">
...