为啥 Zone.js 会改变 AngularJS 评估属性的方式?
Posted
技术标签:
【中文标题】为啥 Zone.js 会改变 AngularJS 评估属性的方式?【英文标题】:Why is Zone.js changing how AngularJS evaluates attributes?为什么 Zone.js 会改变 AngularJS 评估属性的方式? 【发布时间】:2019-01-21 07:22:49 【问题描述】:我有一个包含 Angular (2+) 和 AngularJS (1.x) 的应用程序。我们正在使用第三方 AngularJS 库,它在链接函数中从其 attrs 数组中读取对象,如下所示:
//3rd party lib code:
module.directive('test', () => (
template: `Look at the console`,
link(elt, scope, attrs)
console.log('link attrs.props', attrs.props);
))
模板:
<!-- someObject = name: 'foo' -->
<test props="someObject"></test>
我们刚刚升级到最新版本的 AngularJS,我们发现了一个问题。通常, attrs.props 评估为对象的字符串表示形式。我们没有得到一个字符串化的对象,而是得到“[object Object]”
我尝试了最小的复制,但我无法复制问题,直到我尝试导入 Zone.js,正如您在这个 stackblitz 上看到的那样: https://stackblitz.com/edit/angularjs-attrs-test?file=app.js
如果 Zone.js 被导入(Angular 2+ 需要它),那么attrs.props
就是"[object Object]"
。没有它,attrs.props
就是 name: 'foo'
。
这是一个已知问题吗?有解决办法吗?
【问题讨论】:
【参考方案1】:最好总是先加载 ZoneJS,否则可能会发生一些奇怪的问题。在你的例子中,如果你简单地将 ZoneJS 导入移动到第一行,它就解决了问题。
【讨论】:
【参考方案2】:ZoneJS 覆盖 Object.prototype.toString
方法,这会导致 AngularJS stringify
函数出现意外行为:
function stringify(value)
if (value == null) // null || undefined
return '';
switch (typeof value)
case 'string':
break;
case 'number':
value = '' + value;
break;
default:
if (hasCustomToString(value) && !isArray(value) && !isDate(value))
\/
true
value = value.toString(); // will be called since zone js overrided this method
else
value = toJson(value); // will be called without zonejs
return value;
为了解决这个问题,您可以禁用此补丁:
window.__Zone_disable_toString = false;
import 'zone.js/dist/zone';
Forked Stackblitz
【讨论】:
以上是关于为啥 Zone.js 会改变 AngularJS 评估属性的方式?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在 AngularJS 中的日期输入字段会抛出类型错误?