Apache flex 为什么MXML数据绑定会吞下类型错误?
以下代码应引发错误1009:无法访问空对象引用的属性或方法: 但是,如果它位于由MXML数据绑定设置的setter内部,则不会:Apache flex 为什么MXML数据绑定会吞下类型错误?,apache-flex,data-binding,Apache Flex,Data Binding,以下代码应引发错误1009:无法访问空对象引用的属性或方法: 但是,如果它位于由MXML数据绑定设置的setter内部,则不会: public function set buggySetter(value:String):void { var label:Label; label.text = value; //will fail silently } 要重现这种奇怪的行为,首先,通过扩展s:Label创建一个简单的自定义组件: package { import spa
public function set buggySetter(value:String):void {
var label:Label;
label.text = value; //will fail silently
}
要重现这种奇怪的行为,首先,通过扩展s:Label创建一个简单的自定义组件:
package {
import spark.components.Label;
public class BuggyLabel extends Label {
public function set buggySetter(value:String):void {
var label:Label;
label.text = value; //will fail silently
}
}
}
第二节,将BuggyLabel添加到应用程序并绑定buggySetter:
<fx:Script>
<![CDATA[
[Bindable]
public var foo:String = 'NULL has no properties';
]]>
</fx:Script>
<local:BuggyLabel buggySetter="{foo}"/>
为什么这个应用程序会悄无声息地失败?这个问题的答案其实相当简短:这是Flex SDK工程师做出的架构决定。如果你看一下Flex源代码,你会看到一个try。。。捕获块包含绑定中抛出的大多数错误 Pro:使绑定更容易使用,因为您不必考虑所有可能的错误状态 缺点:如果你知道这可能发生,并且你有很好的单元测试,那么调试可能会更困难,你可以将这方面的挫折感减少到几乎为零 我刚才提到的源代码可以在方法wrapFunctionCall中的“framework”项目中的mx.binding.binding中找到。以下是相关部分:
try {
...
}
catch(error:Error)
{
// Certain errors are normal when executing a srcFunc or destFunc,
// so we swallow them:
// Error #1006: Call attempted on an object that is not a function.
// Error #1009: null has no properties.
// Error #1010: undefined has no properties.
// Error #1055: - has no properties.
// Error #1069: Property - not found on - and there is no default value
// We allow any other errors to be thrown.
if ((error.errorID != 1006) &&
(error.errorID != 1009) &&
(error.errorID != 1010) &&
(error.errorID != 1055) &&
(error.errorID != 1069))
{
throw error;
}
else
{
if (BindingManager.debugDestinationStrings[destString])
{
trace("Binding: destString = " + destString + ", error = " + error);
}
}
}
这个问题的答案实际上相当简短:这是FlexSDK工程师做出的架构决策。如果你看一下Flex源代码,你会看到一个try。。。捕获块包含绑定中抛出的大多数错误 Pro:使绑定更容易使用,因为您不必考虑所有可能的错误状态 缺点:如果你知道这可能发生,并且你有很好的单元测试,那么调试可能会更困难,你可以将这方面的挫折感减少到几乎为零 我刚才提到的源代码可以在方法wrapFunctionCall中的“framework”项目中的mx.binding.binding中找到。以下是相关部分:
try {
...
}
catch(error:Error)
{
// Certain errors are normal when executing a srcFunc or destFunc,
// so we swallow them:
// Error #1006: Call attempted on an object that is not a function.
// Error #1009: null has no properties.
// Error #1010: undefined has no properties.
// Error #1055: - has no properties.
// Error #1069: Property - not found on - and there is no default value
// We allow any other errors to be thrown.
if ((error.errorID != 1006) &&
(error.errorID != 1009) &&
(error.errorID != 1010) &&
(error.errorID != 1055) &&
(error.errorID != 1069))
{
throw error;
}
else
{
if (BindingManager.debugDestinationStrings[destString])
{
trace("Binding: destString = " + destString + ", error = " + error);
}
}
}
此错误1009是错误的
TypeError: Error #1009: Cannot access a property or method of a null object reference.
在你的二传中
public function set buggySetter(value:String):void {
var label:Label; // here is the problem
label.text = value; //will fail silently
}
这里您正在将文本设置为未创建的标签。。。。
您只是指定了标签变量,但没有创建,这就是为什么它会给您上述错误。。。
您应该创建标签varibal或将数据设置为父类
如果
public function set buggySetter(value:String):void {
var label:Label = new Lable();
label.text = value; //now it ll work
}
or
public function set buggySetter(value:String):void {
this.text = value;
}
此错误1009是错误的
TypeError: Error #1009: Cannot access a property or method of a null object reference.
在你的二传中
public function set buggySetter(value:String):void {
var label:Label; // here is the problem
label.text = value; //will fail silently
}
这里您正在将文本设置为未创建的标签。。。。
您只是指定了标签变量,但没有创建,这就是为什么它会给您上述错误。。。
您应该创建标签varibal或将数据设置为父类
如果
public function set buggySetter(value:String):void {
var label:Label = new Lable();
label.text = value; //now it ll work
}
or
public function set buggySetter(value:String):void {
this.text = value;
}
我不是故意初始化标签我不是故意初始化标签+1。这是正确的,在大多数情况下,您实际上希望这种情况发生。绑定的本质是在key:最终出现时检测更改。我们中的绝大多数人都是在视图中设置绑定的,然后期望在分配了一个中介和/或模型来保存我们的数据后,它能够完成真正的工作。如果绑定没有做到这一点,我们将不得不编写一系列锅炉板延迟方法——这使我们的代码更加程序化——对我来说。但是该死的,使用异常来处理常见用例是一个糟糕的想法。仅仅创建所有错误实例的开销就让我不寒而栗。这是正确的,在大多数情况下,您实际上希望这种情况发生。绑定的本质是在key:最终出现时检测更改。我们中的绝大多数人都是在视图中设置绑定的,然后期望在分配了一个中介和/或模型来保存我们的数据后,它能够完成真正的工作。如果绑定没有做到这一点,我们将不得不编写一系列锅炉板延迟方法——这使我们的代码更加程序化——对我来说。但是该死的,使用异常来处理常见用例是一个糟糕的想法。仅创建所有错误实例的开销就让我不寒而栗。