【问题标题】:Ractive two-way databinding with expressions带有表达式的 Ractive 双向数据绑定
【发布时间】:2014-12-18 21:11:25
【问题描述】:

我想要一个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 来动态添加/删除参数输入(例如在某些按键上绑定、使用按钮添加/删除字段等)。

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

【问题讨论】:

    标签: javascript data-binding ractivejs 2-way-object-databinding javascript-databinding


    【解决方案1】:

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

    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>

    【讨论】:

    • 我刚刚来到the same conclusion,但我不确定声明它的正确方式。我也担心控制台警告Two-way binding does not work with expressions...——这只是一个友好的提醒,可以忽略吗?
    • 是的,这只是一条调试消息,以防有人尝试执行 &lt;input value='{{number*2}}'&gt; 并惊讶于输入 10 并没有导致 number 变为 5。它不会导致任何问题你的应用程序,如果元素有twoway='false',消息(应该?)在下一个版本中被压制。
    • 啊...我认为我的问题源于我使用 CDN“最新”而不是“边缘”这一事实——我在每次按键时都收到错误 Uncaught TypeError: Cannot read property 'split' of undefined
    • 所以这可能是一个愚蠢的问题,但是如果您将event 作为参数传递,为什么不直接引用event.context 进行更新,而不是在keypath 上获取/设置;或者就此而言使用event.keypath 而不是重建它?
    • 我已经成功复制了我的最新一期——thisthat,其中每隔一段时间就会抛出 Uncaught TypeError: Cannot read property 'str' of undefined,而下一次点击会转储“缺失”的行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-28
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    相关资源
    最近更新 更多