Это вопрос и ответ, потому что я немного боролся с проблемой, поэтому я хочу отслеживать ее и ее решение.
Надеясь, что это может помочь кому-то, и, возможно, другие люди могут предложить альтернативные решения.
Мой случай: мне пришлось работать над большим проектом 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">
.
Хорошо, если someScopeValue
равен undefined
, директива обнаружит это и предоставит значение по умолчанию, которое перейдет в родительскую область. Раздражает, но в большинстве случаев, вероятно, безвреден. Реальное значение обычно указывается позже (например, после сетевого запроса).
Но иногда в консоли появляется следующая ошибка:
https://code.angularjs.org/1.4.6/docs/error/$compile/nonassign?p0=foo.canEdit%20%26%26%20bar.valid&p1=prjComponent
Я следовал совету, приведенному на соответствующей странице, заменив привязки на "=?"
, но у меня все еще есть ошибка.
В идеале я бы заменил эти привязки на "<?"
, избегая первой проблемы (перезаписи значения в родительской области) и второй (без присваивания выражению).
Но для этого нужен AngularJS 1.5+, и я не могу обновить версию в текущем проекте.
Так как я могу решить эту проблему?