我是Javascript的新手,正在尝试使用Gridster和Knockout。我有一个包含条目的数据库,我使用knockout foreach将它们绑定到UL。UL使用Gridster库设置样式。除非我尝试通过视图模型中的ObservableArray向UL添加额外的元素,否则一切都很好。
有人能帮我理解一下这里的操作范围和顺序吗?感觉像是Gridster库没有对新的小部件进行样式设置。
This jsfiddle展示了这个问题的工作演示。请注意,当您双击一个小部件时,它会创建一个新的小部件,但不会将其放在网格中。取而代之的是,它就像是挂在后面。
这是HTML
<div class="gridster">
<ul data-bind="foreach: myData">
<li data-bind="attr:{
'data-row':datarow,
'data-col':datacol,
'data-sizex':datasizex,
'data-sizey':datasizey
},text:text, doubleClick: $parent.AddOne"></li>
</ul>
</div>这是Javascript
//This is some widget data to start the process
var gridData = [ {text:'Widget #1', datarow:1, datacol:1, datasizex:1, datasizey:1},
{text:'Widget #2', datarow:2, datacol:1, datasizex:1, datasizey:1},
{text:'Widget #3', datarow:1, datacol:2, datasizex:1, datasizey:1},
{text:'Widget #4', datarow:2, datacol:2, datasizex:1, datasizey:1}];
// The viewmodel contains an observable array of widget data to be
// displayed on the gridster
var viewmodel = function () {
var self = this;
self.myData = ko.observableArray(gridData);
//AddOne adds an element to the observable array
// (called at runtime from doubleClick events)
self.AddOne = function () {
var self = this;
myViewModel.myData.push({
text: 'Widget Added After!',
datarow: 1,
datacol: 1,
datasizex: 1,
datasizey: 1
});
};
};
var myViewModel = new viewmodel();
ko.applyBindings(myViewModel);
$(".gridster ul").gridster({
widget_margins: [5, 5],
widget_base_dimensions: [140, 140]
});发布于 2014-06-22 05:34:53
下面是一个完整的JSfiddle示例。在这里,我只突出显示了delete函数
self.deleteOne = function (item) { console.log(item);var widget = $("#“+ item.id);console.log(widget);var column = widget.attr("data-col");if (列){ console.log('Removing ');//如果这被注释掉了,则widget不会重新排列self.gridster.remove_widget(widget,function(){ self.myData.remove(item);console.log('Tiles:'+self.myData().length);});} };
从可观察数组中删除元素的工作是在remove_widget回调中完成的。请参见gridster的documentation。因此,在删除小部件之前执行的removeGridster钩子不再需要执行实际的remove_widget调用。
发布于 2013-11-20 03:49:06
这是一个我认为更符合MVVM模式的工作解决方案:
http://jsfiddle.net/Be4cf/4/
//This is some widget data to start the process
var gridData = [
{id: "1", text:'Widget #1', datarow:1, datacol:1, datasizex:1, datasizey:1},
{id: "2", text:'Widget #2', datarow:1, datacol:2, datasizex:2, datasizey:1},
{id: "3", text:'Widget #3', datarow:1, datacol:4, datasizex:1, datasizey:1},
{id: "4", text:'Widget #4', datarow:2, datacol:1, datasizex:1, datasizey:2}];
// The viewmodel contains an observable array of widget data to be
// displayed on the gridster
var viewmodel = function () {
var self = this;
self.myData = ko.observableArray(gridData);
self.nextId = 5;
self.gridster = undefined;
// AddOne adds an element to the observable array.
// Notice how I'm not adding the element to gridster by hand here. This means
// that whatever the source of the add is (click, callback, web sockets event),
// the element will be added to gridster.
self.addOne = function () {
myViewModel.myData.push({
text: 'Widget Added After!',
datarow: 1,
datacol: 1,
datasizex: 1,
datasizey: 1,
id: self.nextId++
});
};
// Called after the render of the initial list.
// Gridster will add the existing widgets to its internal model.
self.initializeGridster = function() {
self.gridster = $(".gridster ul").gridster({
widget_margins: [5, 5],
widget_base_dimensions: [140, 140]
}).data('gridster');
};
// Called after the render of the new element.
self.addGridster = function(data, object) {
// This bypasses the add if gridster has not been initialized.
if (self.gridster) {
var $item = $(data[0].parentNode);
// The first afterRender event is fired 2 times. It appears to be a bug in knockout.
// I'm pretty new to knockout myself, so it might be a feature too! :)
// This skips the second call from the initial fired event.
if (!$item.hasClass("gs-w"))
{
// This removes the binding from the new node, since gridster will re-add the element.
ko.cleanNode(data[0].parentNode);
// Adds the widget to gridster.
self.gridster.add_widget($item);
// We must update the model with the position determined by gridster
object.datarow = parseInt($item.attr("data-row"));
object.datacol = parseInt($item.attr("data-col"));
}
}
};
};
var myViewModel = new viewmodel();
ko.applyBindings(myViewModel);我仍然需要考虑remove和move事件(在网格中移动应该更新视图模型中项目的x和y值)。我昨天开始使用knockout,所以如果有任何帮助,我将不胜感激。
我找不到最新版本的gridster的cdn。JSFiddle指向了我在Azure中添加的一个临时网站,我会把它放在上面几天,但请随时用你自己的链接更新它。
/
我已经更新了我的代码以支持删除和移动小部件(http://jsfiddle.net/Be4cf/11/),但有一个小问题需要注意:有一个开放的问题(https://github.com/knockout/knockout/issues/1130),它会在调用beforeRemove事件之前清除jquery数据。这会导致gridster崩溃,因为移动其他项所需的数据保存在数据元素中。一种解决办法是保留数据的副本,并在以后将其重新添加到元素中,但我选择了懒惰的方式,并在knockout中注释了有问题的行。
发布于 2013-11-12 20:12:07
在gridster中将class="gs_w“添加到您的li中应该可以
https://stackoverflow.com/questions/19549122
复制相似问题