AngularJS:如何在为缺少的属性提供默认值时避免非分配错误?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AngularJS:如何在为缺少的属性提供默认值时避免非分配错误?相关的知识,希望对你有一定的参考价值。

这是一个问答案例,因为我在这个问题上有点挣扎,所以我希望跟踪它及其解决方案。 希望它可以帮助某人,也许其他人可以提供替代解决方案。

我的情况:我不得不处理一个大型的AngularJS 1.4.6项目(我将其命名为prj),用TypeScript编写,定义了许多带有各种属性的指令(prj-ddd)(prj-aaa),其中一些是布尔值。 他们用字符串绑定实现了这些布尔属性:prjEnabled: "@"prjRequired: "@"。 所以他们测试了这样的值:if ($scope.prjEnabled === "false"),或模板:<div ng-show="prjRequired === 'true'">(是的,没有控制器也用于......)。 这些属性是可选的:显然,这里,prjEnabled默认为"true"prjRequired默认为"false"等,因为当这些值为false时,测试是undefined

这是冗长的,不优雅的(IMO),容易出错(许多原始字符串,隐式默认值),并且效率不高(尽管可能不是以可感知的方式)。

所以我开始用表达式/双向绑定替换这些绑定:prjEnabled: "="prjRequired: "="。 因此,当AngularJS看到<prj-component prj-enabled="false">时,它在指令范围内直接提供了一个布尔值。 不错的触摸:使用这样的文字值,它不会创建任何绑定,因此不会影响性能。 我必须处理缺席属性,所以我在指令的link函数中添加了类似的东西:

if (scope.prjEnabled === undefined) {
    scope.prjEnabled = true;
}

使用成为:if (!$scope.prjEnabled),或模板:<div ng-show="prjRequired">

到现在为止还挺好。但我们也有明确的约束:<prj-component prj-enabled="{{someScopeValue}}">甚至<prj-component prj-enabled="{{foo.canEdit && bar.valid}}">。 由于我们有双向绑定,我只需将它们替换为:<prj-component prj-enabled="someScopeValue"><prj-component prj-enabled="foo.canEdit && bar.valid">。 好吧,如果someScopeValueundefined,该指令将检测到并提供默认值,该值将上升到父范围。烦人,但在大多数情况下,可能是无害的。通常稍后提供实际值(例如,在网络请求之后)。 但有时候,我在控制台中出现以下错误:

https://code.angularjs.org/1.4.6/docs/error/$compile/nonassign?p0=foo.canEdit%20%26%26%20bar.valid&p1=prjComponent

我按照相应页面中给出的建议,用"=?"替换绑定,但我仍然有错误。

理想情况下,我会用"<?"替换这些绑定,避免第一个问题(覆盖父范围中的值)和第二个问题(没有赋值给表达式)。 但这需要AngularJS 1.5+,我无法升级当前项目中的版本。

那么我该如何解决这个问题呢?

答案

它很棘手,我不得不尝试各种解决方案,直到我看到灯光并记住使用"=?"绑定时,有一种方法可以将缺席属性与undefined值区分开来。 我重写了默认值赋值: if (!("prjEnabled" in scope)) { scope.prjEnabled = true; } 如果您不熟悉in运算符,它大致相当于scope.hasOwnProperty("prjEnabled"),但它也会检查原型层次结构。我之所以使用它主要是因为它比函数调用更好/更好...

我制作了一个Plunker应用程序(来自官方AngularJS之一)来重现错误,看看它何时发生,并探索各种情况:qazxsw poi

它显示使用http://plnkr.co/edit/Z2AIag?p=preview绑定并指定默认值(如果未定义),当属性为空(不太可能的情况)或AngularJS静默捕获异常(此处"=",其中wrong.scopeValue && wrong.unknown不存在,导致ReferenceError异常)时出现错误并提供$scope.wrong作为价值。 使用undefined,我们仍然有第二个问题(空属性值不抛出)。 如果我们使用"=?"方法进行测试,我们就会摆脱这种烦人的情况,当"x" is scope是一个后来填充的变量(网络更新等)时很常见。错误仍然可能发生的唯一情况是,如果我们为绑定属性赋值,并且仅在wrong情况下。

另一答案

如何使用默认值手动创建单向绑定:

wrong

对于没有单向绑定的AngularJS(<1.5)版本,可以使用观察程序实现。

以上是关于AngularJS:如何在为缺少的属性提供默认值时避免非分配错误?的主要内容,如果未能解决你的问题,请参考以下文章

null 和 undefined 的区别

javascript null与undefined的区别

在AngularJS中删除输入值时如何再次验证表单

在Angularjs2中更改输入值时如何更新模型值

如何在我的angularjs指令中切换属性的值,如contenteditable?

当缺少某些值时,如何在烛台图表中添加带有注释的线条?