Frage

Ich versuche KnockoutJS zu verwenden, um ein interaktives Dashboard mit Datenbindungen zu verschiedenen Aspekten der style Eigenschaft zu bauen; nämlich left, top, width und height. Zum Beispiel verwende ich JQuery UI zusammen mit ui-ziehbar und ui-veränderbaren Effekten Anwender per Drag-Panels auf einer Leinwand um zu ermöglichen, und die Größe sie jedoch sehen sie fit. Ohne KnockoutJS wurde iterieren ich einfach jedes div und stehlen diese Eigenschaften aus dem DOM-Element. Ich bin sicher, dass es ein besserer Weg KnockoutJS mit, nicht wahr?

Um mein Problem ein wenig besser zu erläutern, betrachten wir zwei Platten nebeneinander:

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

Meine Ansicht Modell sieht so etwas wie dieses (Anmerkung: Pseudo der Kürze halber codiert):

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

Ich möchte es in einer solchen Art und Weise binden, dass, wenn der Benutzer Größen eine der div-Elemente (dh. Die Platten), dass sie dann die darunter liegende Ansichtsmodell würde aktualisieren die eingebauten Datenbindung OnMouseUp verwenden. Dann, wenn der Benutzer die Schaltfläche „Aktualisieren“ klickt, würde ich dann schreiben Sie die Koordinaten an den Server.

Ich denke, es könnte etwas mit benutzerdefinierten Vorlagen zu tun hat, aber auch dort lief ich in einige Komplexitäten, dass ich nicht ganz bei der Verwaltung der Mausereignisse auf jeder Platte erfassen konnte.

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

Ideen?

War es hilfreich?

Lösung

Ich habe genau das gleiche Problem: bind ein KnockoutJS Modell Sammlung von ziehbar und veränderbarer divs. Die Lösung ist kundenspezifische Bindung zu verwenden und das Ereignis Ende Resize und Ende Drag handhaben, da ich a href erklären <= "http://mkramar.blogspot.com/2011/06/jqueryui-draggable-and-resizable- with.html“rel = "nofollow"> hier .

$(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);
        });

Andere Tipps

Mit der Zeit vorbei den Weg, dass es funktioniert ich nicht in der Lage war Green Lösung in JSFiddle und die Lösung von Awais zu sehen schien ein wenig lang, damit ich durch sie einige mehr slugged.

fand ich folgende verbindliche Werke für die Breite einstellen. Die Pars und die ‚px‘ scheinen wichtig zu sein. In meinem Fall 'AWidth' ist die Breite eines div-Tag.

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

Diese Frage wurde auf der KnockoutJS Google-Gruppe von ein brillanter Entwickler namens Grün.

Er demonstrierte, wie dies zu tun, eine benutzerdefinierte Erweiterung Bibliothek (das er gebaut) für KnockoutJS. Seine Lösung erlaubt zusätzliche jQueryUI Ereignisse "bindable" zu sein (dh. Drag & Resize). Er stellte dann seine Lösung zusammen mit seinem Knockout-ext.js auf JSFiddle Datei aus für mich, es zu benutzen und zu lernen.

Nochmals vielen Dank, Grün ! :)

Ich konnte es mit einer einfachen Lösung zum Laufen bringen, baut es aus Ryans Ansicht.

Dies ermöglicht es mir, meine Änderungen in Echtzeit, wie ich Drag & Drop-Elemente zu speichern, mit BreezeJS

in Ansichtsmodell

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

und meine Ansicht

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top