为什么 Zone.js 改变 AngularJS 评估属性的方式?

Rya*_*lva 5 angularjs zone.js angular angular-hybrid

我有一个同时包含 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);
  }
})) 
Run Code Online (Sandbox Code Playgroud)

模板:

<!-- someObject = {name: 'foo'} -->
<test props="{{someObject}}"></test>
Run Code Online (Sandbox Code Playgroud)

我们刚刚升级到最新版本的 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'}

这是一个已知的问题?有解决方法吗?

yur*_*zui 3

ZoneJS 重写Object.prototype.toString方法会导致 AngularJSstringify函数出现意外行为:

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;
}
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,您可以禁用此补丁:

window.__Zone_disable_toString = false; 
import 'zone.js/dist/zone';
Run Code Online (Sandbox Code Playgroud)

叉式堆栈闪电战