0

我想要一个input表示原始(字符串,数字)值的列表,以便您可以将它们作为逗号分隔值输入,但将模型更新为数组:

"Transforms": [
        {
            "Fn": "TheFunctionName",
            "Args": [ "arg1", 2, "arg3" ]
        },
        {
            "Fn": "AnotherMethod",
            "Args": [ 4.678 ]
        },
    ]

将被管理:

{{#each Transforms:i}}
   <li>
       <input value="{{Fn}}" placeholder="Function Name" />
       <input value="{{implode(Args)}}" placeholder="Function Arguments" />
   </li>
{{/each}}

并会呈现如下内容:

* [ TheFunctionName ] [ "arg1", 2, "arg3" ] * [ AnotherMethod ] [ 4.678 ]

主要是因为我不需要找出一个好的 UI 来动态添加/删除参数输入(比如在某些按键上绑定,使用按钮添加/删除字段等)。

我可以使用“占位符”属性进行数据绑定,并且可能会观察到更新实际属性,但是在“序列化”底层模型时我需要将其过滤掉。似乎我可以使用具有 getter 和 setter 的计算属性,但从文档中不清楚它如何与列表中的嵌套属性一起使用(即列表中有许多条目dataTransforms

4

1 回答 1

0

这里的技巧是不使用双向绑定,而是使用更传统的事件处理技术。此示例侦听每个change中的第二个输入上的事件(不是input事件,每次击键都会发生,因为这会导致光标在用户仍在键入时四处跳动)<li>,并尝试评估其内容。同时,格式化程序接受参数并将它们转换回字符串:

var ractive = new Ractive({
    el: 'main',
    template: '#template',
    data: {
        transforms: [
            {
                fn: 'TheFunctionName',
                args: [ 'arg1', 2, 'arg3' ]
            },
            {
                fn: 'AnotherMethod',
                args: [ 4.678 ]
            }
        ],
        format: function ( args ) {
            return args.map( JSON.stringify ).join( ', ' );
        }    
    },
    updateArgs: function ( index, str ) {
        var keypath = 'transforms[' + index + '].args',
            args = this.get( keypath );
        
        try {
            // or use JSON.parse, if you don't want to eval
            this.set( keypath, eval( '([' + str + '])' ) );
        } catch ( err ) {
            // reset
            this.set( keypath, null );
            this.set( keypath, args );
        }
    }
});
<script src="http://cdn.ractivejs.org/edge/ractive.js"></script>

<main></main>

<script id='template' type='text/ractive'>
    <h2>input</h2>
    <ul>
        {{#each transforms:i}}
            <li>
                <input value='{{fn}}' placeholder='function name'/>
                <input
                    twoway='false'
                    value='{{format(args)}}'
                    placeholder='function arguments'
                    on-change='updateArgs(i,event.node.value)'
                />
            </li>
        {{/each}}
    </ul>
    
    <h2>output</h2>
    <ul>
        {{#each transforms}}
            <li>
                <p>function name: <strong>{{fn}}</strong></p>
                <p>args:</p>
                <ul>
                    {{#each args}}
                        <p>{{JSON.stringify(this)}} ({{typeof this}})</p>
                    {{/each}}
                </ul>
            </li>
        {{/each}}
    </ul>
</script>

于 2014-12-18T22:26:12.763 回答