Как привязать ширину / высоту div к полям формы?

#javascript #jquery #jquery-ui #knockout.js

#javascript #jquery #jquery-пользовательский интерфейс #knockout.js

Вопрос:

Я хочу создать несколько div элементов, которые я могу перемещать и изменять размер, и привязать их width , height и т.д. к объекту в массиве. Итак, если я создам шесть divs, у меня будет шесть объектов в моем массиве, каждый объект имеет .width , .height и т.д.

Я не совсем понимаю, как я мог бы привязать вводимый текст к свойствам объекта array, используя knockout.js . Вот моя попытка:

 var counter = 0;
var objects = [];

$(document).ready(function () {
    dostuff($("#main"));  // give it a target container div
});

function dostuff(target) {
    counter  ;
    // create a div containing a span and an input that binds to knockout.js

    target.append('<div id="d'   counter   '">width:<span id="d'   counter  
        '" data-bind="text:objects['   counter   '].width"></span>'  
        '<input type="text" id="d'   counter   
        '" data-bind="value:objects['   counter   '].width"/></div>');

    var a = $("#d"   counter);
    a.css("position", "absolute");
    a.css("width", "100px");
    a.css("height", "100px");
    a.css("background-color", "#"   
        Math.ceil(Math.random()*9)   "0"  
        Math.ceil(Math.random()*9)   "0"  
        Math.ceil(Math.random()*9)   "0");
    a.resizable({
        stop: function (e, ui) {
            this.childNodes[2].value = ui.size.width; 
        }
    });
    objects[counter] = { width: "100px", height: "100px", 
        top: "0px", left: "0px" };
    ko.applyBindings(objects[counter]);
}
  

Как бы я получил objects[1].width привязку к <input> значению div d1?

Ответ №1:

Минимальное количество изменений, которые вам пришлось бы внести, чтобы это произошло, заключалось бы в выполнении чего-то вроде:

  target.append('<div id="d'   counter   '" data-bind="style: { width: width , height: height, top: top, left: left } }">width:<span id="d'   counter  
        '" data-bind="text: width"></span>'  
        '<input type="text" id="d'   counter   
        '" data-bind="value: width"/></div>');
  

Итак, здесь используется style привязка к вашему основному div. Кроме того, поскольку вы вызываете applyBindings для объектов [счетчик], вы можете ссылаться на свойства непосредственно в привязках (а не через objects [счетчик]).

Если вы вызываете эту функцию несколько раз, то вам нужно быть осторожным с тем, как вы вызываете ko.applyBindings . Если вы не передадите второй параметр, то он будет применен ко всему документу. Вы действительно хотите сделать это только один раз. В вашем случае вы, вероятно, захотите передать второй параметр, чтобы указать точный корневой элемент для начала. Итак, вы бы назвали что-то вроде ko.applyBindings(objects[counter], $("#d" counter)[0]);

Я не знаю вашего точного варианта использования, но если бы это был я, я бы сначала создал свой массив объектов, а затем использовал шаблон для построения divs. Тогда в разметке у меня был бы контейнер, который вызывает template привязку с foreach опцией передачи массива. Затем вы должны создать шаблон, содержащий разметку для каждого div. Таким образом, вы можете избежать построения разметки в виде строк. Если вам нужен пример выполнения чего-то подобного, дайте мне знать.

Надеюсь, это поможет.

Комментарии:

1. Вот краткий пример способа выполнения привязки, при котором div привязывается с помощью style привязки для установки значений из объекта и использует event привязку для отслеживания обновлений с помощью перетаскивания или изменения размера. jsfiddle.net/rniemeyer/a6Gjs

2. Ваш ответ был ответом «выбей это из парка». Я действительно ценю это.

3. Превосходный пример на jsFiddle. Заставил меня решить другую проблему, которая у меня была.