Почему Zone.js меняет способ оценки атрибутов AngularJS?

У меня есть приложение с 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 оценивает строковое представление объекта. Вместо получения строкового объекта мы получаем «[объект объекта]»

Я попытался воспроизвести минимальное количество раз, но не смог воспроизвести проблему, пока не попытался импортировать 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'}.

Это известная проблема? Есть ли обходной путь?


person Ryan Silva    schedule 14.08.2018    source источник


Ответы (2)


Рекомендуется всегда загружать ZoneJS раньше всего, иначе могут возникнуть такие странные проблемы. В вашем примере, если вы просто переместите импорт ZoneJS в первую строку, это решит проблему.

person William Grasel    schedule 15.08.2019

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';

раздвоенный Stackblitz

person yurzui    schedule 15.08.2019