Подтвердить что ты не робот

Как связать объект с элементом DOM

У меня есть главный объект в моей настройке JS, то есть:

var myGarage = {
    cars: [
        {
            make: "Ford",
            model: "Escape",
            color: "Green",
            inuse: false
        },
        {
            make: "Dodge",
            model: "Viper"
            color: "Red",
            inuse: true
        },
        {
            make: "Toyota",
            model: "Camry"
            color: "Blue",
            inuse: false
        }
    ]
}

Теперь я перебираю свои машины и кладу их в стол. В таблице у меня также есть кнопка, которая позволяет мне переключать автомобиль как "в использовании" и "не используется".

Как я могу связать элемент DOM каждой строки с соответствующим автомобилем, так что если я переключу флаг "inuse", я могу обновить главный объект?

4b9b3361

Ответ 1

Я бы предложил рассмотреть addEventListener и конструктор, который соответствует вашим объектам интерфейсу eventListener.

Таким образом, у вас может быть хорошая связь между вашим объектом, вашим элементом и его обработчиками.

Чтобы сделать это, создайте конструктор, специфичный для ваших данных.

function Car(props) {
    this.make = props.make;
    this.model = props.model;
   // and so on...

    this.element = document.createElement("div"); // or whatever

    document.body.appendChild(this.element);      // or whatever

    this.element.addEventListener("click", this, false);
}

Затем реализуем интерфейс:

Car.prototype.handleEvent = function(e) {
    switch (e.type) {
        case "click": this.click(e);
        // add other event types if needed
    }
}

Затем создайте свой обработчик .click() на прототипе.

Car.prototype.click = function(e) {
    // do something with this.element...
    this.element.style.color = "#F00";

    // ...and the other properties
    this.inuse = !this.inuse
}

Итак, вы можете просто перебрать Array и создать новый объект Car для каждого элемента, и он создаст новый элемент и добавит слушателя (ов).

myGarage.cars.forEach(function(obj) {
    new Car(obj)
})

Ответ 2

Фактически вы можете прикреплять объект непосредственно к node:

var n = document.getElementById('green-ford-escape');
n.carObject = myGarage.cars[0];
n.onclick = function() {
  doSomethingWith(this.carObject);
}

Для того же и для устранения неоднозначности, в некоторых случаях, более ясно записать вышеупомянутый обработчик событий, чтобы ссылаться на n вместо this:

n.onclick = function() {
  doSomethingWith(n.carObject);
}

Вы также можете ссылаться непосредственно на объект из присоединенного события:

var n = document.getElementById('green-ford-escape');
n.onclick = function() {
    doSomethingWith(myGarage.cars[0]);
}

В последнем случае myGarage не должно быть глобальным. Вы можете сделать это и ожидать, что он будет работать правильно:

(function(){

    var myGarage = { /* ... etc ... */ };

    var n = document.getElementById('green-ford-escape');
    n.onclick = function() {
        doSomethingWith(myGarage.cars[0]);
    }

})();

Функция события node корректно "удерживает" локальную переменную, эффективно создавая закрытую переменную.

Вы можете протестировать это в консоли Chrome/FF/IE:

var o = {a: 1};
var n = document.createElement('div');
n.innerHTML = "click me";
n.data = o;
n.onclick = function() { n.data.a++; console.log(n.data, o); }
document.body.appendChild(n);

Вы должны увидеть в журнале консоли два одинаковых объекта с каждым щелчком, каждый с возрастающими значениями a.

Остерегайтесь, что установка n.data для примитива не создаст ссылку. Он скопирует значение.

Ответ 3

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

Итак, когда вы переходите через:

for (var i = 0, l = array.length; i < l; i++) {
  var div = '<tr data-car="' + JSON.stringify(array[i]) + '" data-index="' + i + '"><td></td></tr>'
}

И в событии click:

$('button').click(function() {
    var carIndex = $(this).closest('tr').attr('data-index');
    var carData = $(this).closest('tr').attr('data-car');
    if (carData) carData = JSON.parse(carData);

    myGarage.cars[carIndex].inUse = true;
})

Если вы привязываете данные к DOM, вам может даже не понадобиться обновлять фактические данные JS. Можно перебирать каждую строку в таблице и воссоздавать объект данных, из которого вы создали таблицу.

Ответ 4

Вы можете использовать атрибут data5 * HTML5, чтобы узнать, какая строка это. Вы должны делать что-то вроде этого

var table = $('<table>'); // Let create a new table even if we have an empty table in our DOM. Simple reason: we will achieve single DOM operation (Faster)

for (var i=0; i<myGarbage.cars.length; i++) {
    // Create a new row and append to table
    var tr = $('<tr>').appendTo(table);

    var carObject = myGarbage.cars[i];
    // Traverse the JSON object for each car
    for (var key in carObject) {
        // Create other cells. I am doing the last one
        var td = $('<td>').appendTo(tr);
        var button = $('<button>').attr('data-carId', i).addClass('toggle-inuse').appendTo(td);
    }
}
// If en ampty table awaits me in DOM
$('#tableId').html(table.html());

Теперь мы добавим прослушиватель событий на кнопку: -

$('.toggle-inuse').click(function() {
    var i = $(this).data('carId');
    myGarbage.cars[i].inuse = !myGarbage.cars[i].inuse; //Wow done
}

Попробуйте это!