【问题标题】:Async binding in AureliaAurelia 中的异步绑定
【发布时间】:2016-08-25 19:16:08
【问题描述】:

我正在尝试将异步值绑定到我的 Aurelia 模板之一,显然我得到的只是[object Promise] 作为回报。

我发现这篇文章http://www.sobell.net/aurelia-async-bindings/ 很好地解释了如何使用如下所示的绑定行为来解决这个问题:

// http://www.sobell.net/aurelia-async-bindings/
export class asyncBindingBehavior {
    bind (binding, source) {
        binding.originalUpdateTarget = binding.updateTarget;

        binding.updateTarget = a => {
            if (typeof a.then === 'function') {
                binding.originalUpdateTarget('...');

                a.then(d => {
                    binding.originalUpdateTarget(d);
                });
            }
            else {
                binding.originalUpdateTarget(a);
            }
        };
    }

    unbind (binding) {
        binding.updateTarget = binding.originalUpdateTarget;
        binding.originalUpdateTarget = null;
    }
}

当 Promise 使用字符串或其他非对象类变量解析时,这非常有效。

但是如果我的 promise 用一个对象来解决呢?我将如何访问该对象内我需要的属性?

因为如果我这样做:${object.property & async} 在我的模板中,那么它将失败,因为 object.property 不是承诺 - 只有 object 是。

我添加了一些技巧,允许我将属性指定为async 的参数,如下所示:${object & async:'property'} 并更新了我的绑定行为:

// http://www.sobell.net/aurelia-async-bindings/
export class asyncBindingBehavior {
    bind (binding, source, property) {
        binding.originalUpdateTarget = binding.updateTarget;

        binding.updateTarget = a => {
            if (typeof a.then === 'function') {
                binding.originalUpdateTarget('...');

                a.then(d => {
                    if (property) {
                        binding.originalUpdateTarget(d[property]);
                    }
                    else {
                        binding.originalUpdateTarget(d);
                    }
                });
            }
            else {
                binding.originalUpdateTarget(a);
            }
        };
    }

    unbind (binding) {
        binding.updateTarget = binding.originalUpdateTarget;
        binding.originalUpdateTarget = null;
    }
}

但这对我来说很像一个 hack,而且它也不允许我访问任何更深层次的属性,例如 object.parent.child

我还在 GitHub 上发现了这个(相当老的)问题:https://github.com/aurelia/templating/issues/81,他们使用了getValue 方法。我从来没有听说过这种方法并且尝试使用它失败了,所以我完全不确定它是如何工作的......

有什么想法吗?

【问题讨论】:

    标签: promise aurelia


    【解决方案1】:

    您可以通过将函数指定为第三个参数来回避您的难题,从而提供比简单属性提取更多的灵活性。

    你可以这样写:

    export class asyncBindingBehavior {
        bind (binding, source, transformer="default") {
            binding.originalUpdateTarget = binding.updateTarget;
            binding.updateTarget = a => {
                if (typeof a.then === 'function') {
                    binding.originalUpdateTarget('...');
                    a.then(d => binding.originalUpdateTarget(transformFunctions[transformer](d)));
                } else {
                    binding.originalUpdateTarget(a);
                }
            };
        }
        unbind (binding) {
            binding.updateTarget = binding.originalUpdateTarget;
            binding.originalUpdateTarget = null;
        }
    }
    

    transformFunctions 查找将是必要的(?),因为 Aurelia 绑定被指定为 HTML-ebbedded 或模板指令的方式(即所有参数必须是字符串)。除非 Aurelia 提供更好的“传递函数”(Value Converters?) 更好的方法,否则你会这样写:

    export var transformFunctions = {
        default: (d) => d,
        transform1: (d) => d.someProperty,
        transform2: (d) => d.someProperty.someOtherProperty,
        transform3: someFunction,
        transform4: someOtherFunction.bind(null, someData);
    }
    

    当然,你会给函数起更好的名字。

    【讨论】:

    • 嗯,我明白你的意思了。我想一个函数会更有意义,因为我可以做任何我想做的事情来提取我需要的值。但这真的是最好的方法吗?理想情况下,我会喜欢 ${object.property & async} 之类的东西。也许我可以以某种方式从property“走到”object??
    • 当然,您可以传递一个“dot.separated.property.string”.split('.') 然后关联地向下钻取以提取 d["dot"]["separated"]["property"]["string"] 但这肯定不如函数灵活,并且可以说更乱。
    • 好的,我将把这个问题留待一段时间,看看是否有更多建议。
    • 和你一样,我很想知道是否有更好的方法。
    猜你喜欢
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多