Как привязать данные к вершине, слева, ширине и высоте CSS-элемента DOM? - PullRequest
3 голосов
/ 17 января 2011

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

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

<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>

Идеи

Ответы [ 4 ]

5 голосов
/ 31 мая 2012

Со временем я так и не смог увидеть решение Грина в JSFiddle, и решение от Awais показалось мне немного длинным, поэтому я пролистал его еще немного.для настройки ширины.Паренс и «px» кажутся важными.В моем случае 'AWidth' - это ширина тега div.

data-bind="style: {width: AWidth() + 'px'}"
3 голосов
/ 01 июня 2011

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

$(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);
        });
0 голосов
/ 29 апреля 2013

Мне удалось заставить его работать с помощью простого решения, оно построено на представлении Райана.

Это позволяет мне сохранять изменения в режиме реального времени при перетаскивании перетаскиваемых элементов с помощью 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>

0 голосов
/ 27 января 2011

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

Он продемонстрировал, как это сделать, используя пользовательскую библиотеку расширений (которую он построил) для KnockoutJS. Его решение позволяет привязывать дополнительные события JQueryUI (т. Е. Перетаскивать и изменять размер). Затем он разместил свое решение вместе со своим файлом knockout-ext.js на JSFiddle, чтобы я мог использовать его и учиться на нем.

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

...