创建可排序的自定义标记会失去可观察性

时间:2017-05-15 12:27:14

标签: jsviews

我有一个目录文件的对象列表。然后,用户可以选择排序顺序(名称,日期等),并添加更多项目。

排序后,观察者正确更新数据并刷新自定义标记。但是,当我添加新项目时,自定义标记不会收到相同的刷新触发器。

我的自定义{{sort}}代码基本上执行以下操作:

  1. 循环&将对象列表转换为数组(以允许排序)。
  2. 按提供的索引(名称等)对数组进行排序。
  3. 循环&构建渲染HTML。
  4. 我的数据:

    {
        '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之外,我找不到像我这样的场景。

    我受到以下限制:

    • 数据是一个对象列表,可以是一个对象数组。
    • JSViews v1.0.0-alpha 52(我知道,不是最新的!)。

    我尝试使用标记属性来恢复可观察性,如:

    boundProps : ['items', 'index', 'direction'],
    dataBoundOnly : true,
    autoBind : true,
    

    这是一个简化的例子,如果错误最初并不明显,我会尝试做一个小提琴。任何指针都将非常感谢!

    谢谢!

1 个答案:

答案 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}}标记,它将项目对象的可观察哈希值转换为可观察的项目数组 - 类似于上面的数据设计和方案。请参见此处的示例: