我有一个目录文件的对象列表。然后,用户可以选择排序顺序(名称,日期等),并添加更多项目。
排序后,观察者正确更新数据并刷新自定义标记。但是,当我添加新项目时,自定义标记不会收到相同的刷新触发器。
我的自定义{{sort}}
代码基本上执行以下操作:
我的数据:
{
'file1-id' : { name : 'file.txt', date : 1470123456 },
...
}
我的HTML:
{^{sort prop.items ~root.sort.index ~root.sort.direction}}
{^{:item.name}}
{{/sort}}
我的JS:
$.views.tags({
/**
* @usage {^{sort items keyname desc}} {{:i}}{{:key}}{^{:item.property}} {{/sort}}
*
* @param mixed $items An Object of Items to Loop & Render.
* @param string $index The Name of the Item Key to Order by (name|date|size.x).
* @param string $direction The Direction to Order by (asc = old -> new, desc = new -> old).
*/
sort : function( items, index, direction )
{
var results = [];
var segments = index.split( '.' );
var deep = segments.length > 1; // Check whether a nested index ( e.g. size.x)
// Render Each Item to an Array
$.each( items, $.proxy( function( key, el )
{
// Skip jQuery Observer Event Items Which are in the List (jQuery12313847623846)
if( !el.data || !el.events )
{
var keyval = null;
// Search for nested index
if( deep && el.hasOwnProperty( segments[0] ) && el[segments[0]].hasOwnProperty( segments[1] ) )
{
var keyval = el[segments[0]][segments[1]];
}
else if( el.hasOwnProperty( segments[0] ) )
{
var keyval = el[segments[0]];
}//end if
// Keep Hold of Keys for Sorting
results.push(
{
key : keyval,
item : el
});
}//end if
}, this ) );
// Sort Items
if( segments[0] )
{
results = results.sort( function( a, b )
{
if( direction == 'asc' )
{
return a.key > b.key ? 1 : -1;
}
else
{
return a.key < b.key ? 1 : -1;
}//end if
});
}//end if
// Traverse, Render Item HTML, Implode & Return
return $.map( results, $.proxy( function( el, i )
{
return this.tagCtx.render( { i : i, key : el.key, items : results, item : el.item } );
}, this ) ).join( "\n" );
},
});
将对象转换为数组会失去其可观察性,还是问题出在其他地方?
我浏览了一些文档,但除了range control之外,我找不到像我这样的场景。
我受到以下限制:
我尝试使用标记属性来恢复可观察性,如:
boundProps : ['items', 'index', 'direction'],
dataBoundOnly : true,
autoBind : true,
这是一个简化的例子,如果错误最初并不明显,我会尝试做一个小提琴。任何指针都将非常感谢!
谢谢!
答案 0 :(得分:2)
您的自定义{{sort}}标记只是一个函数 - 所以只是一个渲染方法。要提供完整的可观察控制,您需要更多...
在这种情况下,您希望标记采用项目对象的对象哈希并将其呈现为可观察的项目集合。这样做的方法是使用JsViews Observable Map功能,该功能从基于一个模型的可观察数据映射到基于不同模型的可观察数据。
Observable Map尚未完整记录,但您可以在以下示例中看到它的使用方式:
简单的排序表格
标签:
{^{forPlus list.rows ^sortby=list.sortby ^reverseSort=list.reverseSort ~list=list}}
代码:
$.views.tags({
forPlus: {
baseTag: "for",
dataMap: $.views.map({
getTgt: getTargetItems,
obsSrc: observeSourceItems
}),
onUpdate: function() {
this.tagCtx.map.update();
}
}
});
排序表格网格视图(更复杂的示例):
JsViews {{props}}标记 - 从对象映射到数组(属性数组):
更高级的案例:可排序的{{forHash}}
标记,它将项目对象的可观察哈希值转换为可观察的项目数组 - 类似于上面的数据设计和方案。请参见此处的示例: