Как привязать данные к вершине CSS, слева, ширине и высоте элемента DOM?

StackOverflow https://stackoverflow.com/questions/4717485

Вопрос

Я пытаюсь использовать nockoutjs для создания интерактивной панели панели с привязками данных в разных аспектах style имущество; а именно left, top, width, а также height. Анкет Например, я использую пользовательский интерфейс jQuery, а также эффекты, позволяющие пользователям, позволяющие пользователям перетаскивать панели на холсте и изменить их размер, как они не считают нужным. Без KnockoutJS я просто переживал каждый DIV и крал эти свойства из элемента DOM. Я уверен, что есть лучший способ использования nockoutjs, верно?

Чтобы объяснить мою проблему немного лучше, рассмотрите две панели рядом:

<div id='dashboard'> 
  <div id='panel1' class='ui-draggable ui-resizable' data-bind='?????'> 
    <!-- content goes here -->
  </div> 
  <div id='panel2' class='ui-draggable ui-resizable' data-bind='?????'> 
    <!-- content goes here --> 
  </div> 
  <button data-bind='click: send'>Update</button> 
</div> 

Моя модель просмотра выглядит примерно так (примечание: псевдо, закодированный для краткости):

var viewModel = { 
  panels: [ 
   { id: 'panel1', left: 0, top: 0, width: 50; height: 50 }, 
   { id: 'panel2', left: 50, top: 0, width: 50; height: 50 } ], 
  send: function() { 
   ko.utils.postJson( location.href , { panels: this.panels } ); 
  } 
}; 
ko.applyBindings( '#dashboard', viewModel ); 

Я хотел бы связать это таким образом, чтобы, когда пользователь размещает какие -либо элементы DIV (т.е. панели), он затем обновил бы базовую ViewModel, используя встроенное привязка данных OnMouseUp. Анкет Затем, когда пользователь нажимает кнопку «Обновление», я затем разместил координаты на сервере.

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

<script type='text/html' id='panelTemplate'>
    <div class='ui-draggable ui-resizable' 
         style='top: ${ top }; left: ${ left }; width: ${ width }px; height: ${ height }px;'>
        <!-- content goes here -->
    </div>
</script>

Идеи?

Это было полезно?

Решение

У меня была такая же проблема: свяжите модель нокаутирования с коллекцией Draggable и Resizable Divs. Решение состоит в том, чтобы использовать пользовательскую привязку и обрабатывать событие конца изменения размера и конец сопротивления, как я объясняю здесь.

$(document).ready(function () {
            $('#btnSave').click(function () {
                $.ajax({
                    url: '/Save.ashx',
                    contentType: "application/json; charset=utf-8",
                    type: 'POST',
                    dataType: 'json',
                    data: ko.toJSON(viewModel),
                    error: function () { alert("ajax error"); }
                });
            });

            ko.bindingHandlers.jqDraggableResizable = {
                init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
                    var obj = valueAccessor();
                    var $elem = $(element);

                    element.dataObj = obj;

                    $elem.resizable({
                        stop: function (event, ui) {
                            this.dataObj.H(ui.size.height);
                            this.dataObj.W(ui.size.width);
                        }
                    });

                    $elem.draggable({
                        stop: function (event, ui) {
                            this.dataObj.X(ui.position.left);
                            this.dataObj.Y(ui.position.top);
                        }
                    });
                }
            }

            ko.applyBindings(viewModel);
        });

Другие советы

Со временем, проходя из того, как это происходит, я не смог увидеть решение Грина в JSfiddle, и решение от Awais казалось немного длинным, поэтому я пробил его еще немного.

Я нашел следующие работы для установки ширины. Паренс и «PX» кажутся важными. В моем случае «Awidth» - ширина тега Div.

data-bind="style: {width: AWidth() + 'px'}"

На этот вопрос был ответ на Nockoutjs Google Group блестящим разработчиком по имени Грин.

Он продемонстрировал, как это сделать, используя пользовательскую библиотеку расширения (которую он построил) для nockoutjs. Его решение позволяет дополнительным событиям jqueryui быть «связывающими» (т.е. перетаскивание и изменение размера). Затем он опубликовал свое решение вместе со своим файлом nockout-ext.js на JSFiddle, чтобы я мог использовать и учиться на нем.

Еще раз спасибо, зеленый! :)

Я смог заставить его работать с простым решением, оно создает представление Ryans.

Это позволяет мне сохранить мои изменения в реальном времени, когда я перетаскиваю элементы капли, с Breezejs

в ViewModel

ko.bindingHandlers.draggable = {
    init: bindDraggable
};

function bindDraggable(element, value) {
    $(element).draggable({
        stop: onStopDrag
    });

    function onStopDrag(event, ui) {
        ko.dataFor(element).PositionX(ui.position.left);
        ko.dataFor(element).PositionY(ui.position.top);
        datacontext.saveChanges(); //if you want real time updating on drop
    }
}

И на мой взгляд

<div data-bind="foreach: posts">
<div class="BoardPost" data-bind="style: { top: PositionY() + 'px', left: PositionX() + 'px' }, draggable:null">
    <div class="Title" data-bind="text: Content"></div>
</div>

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top