Aurelia的异步绑定



我试图将异步值绑定到我的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是。

我添加了一点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方法。我从来没有听说过这种方法,尝试使用它失败了,所以我不确定它是如何工作的…

任何想法?

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

你可以这样写:

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或模板指令(即所有参数必须是String)。除非Aurelia提供了一种更好的方式来"传递函数"(值转换器?),否则您应该这样写:

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

当然,你可以给函数起个更好的名字

最新更新