Aurelia中的异步绑定

时间:2016-08-24 14:28:20

标签: promise aurelia aurelia-binding

我试图将异步值绑定到我的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使用字符串或其他非类似对象的变量解析时,这非常有效。

但是如果我的承诺与对象一起解决怎么办?我将如何访问该对象中需要的属性?

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

我添加了一些hack,允许我将属性指定为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;
    }
}

但这对我来说非常像黑客,它也不允许我访问任何更深层的属性,如object.parent.child

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

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

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

你可以这样写:

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;
    }
}

由于Aurelia绑定被指定为HTML-ebbedded或模板指令(即所有params必须为String),因此transformFunctions查找是必要的(?)。除非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);
}

当然,您可以为函数提供更好的名称。