DOM要素のCSS上部、左、幅、高さにデータをバインドする方法は?
-
12-10-2019 - |
質問
knockoutjsを使用して、さまざまな側面にデータバインディングを使用してインタラクティブなダッシュボードを構築しようとしています。 style
財産;すなわち left
, top
, width
, 、 と height
. 。たとえば、jquery UIを使用してUIドラッグ可能でUIに頼る可能性のあるエフェクトを使用して、ユーザーがパネルをキャンバスにドラッグしてサイズを変更できるようにします。 Knockoutjsがなければ、私は各Divを繰り返して、これらのプロパティをDOM要素から盗んでいました。 Knockoutjsを使用するより良い方法があると確信していますよね?
私の問題をもう少し詳しく説明するには、2つのパネルを並べて検討してください。
<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>
アイデア?
解決
私はまったく同じ問題を抱えていました:ノックアウトJSモデルをドラッグ可能でresizapable Divのコレクションにバインドします。解決策は、カスタムバインディングを使用し、Dragの変更と終了の終わりのイベントを処理することです。 ここ.
$(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の解決策が少し長く見えたので、もう少しゆっくりと鳴り響きました。
幅を設定するために、次のバインディングが機能しました。 Parensと「PX」は重要のようです。私の場合、「Awidth」はDivタグの幅です。
data-bind="style: {width: AWidth() + 'px'}"
この質問には答えられました Knockoutjs Google Group Greenという名前の素晴らしい開発者によって。
彼は、Knockoutjsのカスタム拡張機能(彼が構築した)を使用してこれを行う方法を実証しました。彼のソリューションにより、追加のjQueryuiイベントが「バインド可能」になります(つまり、ドラッグ&サイズ変更)。その後、彼は彼のソリューションをjsfiddleにノックアウト-ext.jsファイルとともに投稿して、私がそれを使用して学習するために掲載しました。
もう一度ありがとう、グリーン! :)
私はそれを簡単なソリューションで動作させることができました、それはライアンの見解を構築します。
これにより、ドロップ要素をドラッグするときに変更をリアルタイムで保存することができます。
ビューモデル
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>