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

时间:2018-08-14 12:23:47

标签: angularjs angular zone.js 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);
  }
})) 

模板:

<!-- 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'}

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

一个好习惯是始终先加载ZoneJS,否则可能会发生一些奇怪的问题。在您的示例中,如果仅将ZoneJS导入移动到第一行,就可以解决此问题。