Ответ 1
Вот почему я отказался от ответа.
Во-первых, вы никогда не должны использовать '=' для передачи ссылок на директивы.
'=' создает две часы и использует их, чтобы гарантировать, что как область директивы, так и ссылки на родительские объекты одинаковы (двусторонняя привязка). Это действительно плохая идея разрешить директиву изменять определение функции в вашей родительской области, что и происходит, когда вы используете этот тип привязки. Кроме того, часы должны быть сведены к минимуму - в то время как он будет работать, две дополнительные часы не нужны. Так что это не нормально - часть пониженного голосования заключалась в том, чтобы предположить, что это было.
Во-вторых - ответ искажает то, что '&' делает. и не является "односторонним связыванием". Это неправильно понимает, потому что, в отличие от '=', он не создает никаких $часов и изменение значения свойства в области директивы не распространяется на родителя.
Согласно документам:
& или & attr - обеспечивает способ выполнения выражения в контексте родительская область
Когда вы используете и в директиве, он генерирует функцию, которая возвращает значение выражения, вычисленного против родительской области. Выражение не должно быть вызовом функции. Это может быть любое допустимое выражение angular. Кроме того, эта сгенерированная функция принимает аргумент объекта, который может переопределять значение любой локальной переменной, найденной в выражении.
Чтобы расширить пример OP, предположим, что родитель использует эту директиву следующим образом:
<my-component foo="go()">
В директиве (функция шаблона или ссылки), если вы вызываете
foo({myVal: 42});
Что вы делаете, это вычисление выражения "go()", которое вызывает функцию "go" в родительской области, не передавая никаких аргументов.
В качестве альтернативы,
<my-component foo="go(value)">
Вы оцениваете выражение "go (value)" в родительской области, которое будет в основном вызывать $parent.go($ parent.value) "
<my-component foo="go(myVal)">
Вы оцениваете выражение "go (myVal)", но до того, как выражение будет оценено, myVal будет заменен на 42, поэтому оцененное выражение будет "go (42)".
<my-component foo="myVal + value + go()">
В этом случае $scope.foo({myVal: 42}) вернет результат:
42 + $parent.value + $parent.go()
По существу, этот шаблон позволяет директиве "вводить" переменные, которые потребитель директивы может по желанию использовать в выражении foo.
Вы можете сделать это:
<my-component foo="go">
и в директиве:
$scope.foo()(42)
$scope.foo() будет оценивать выражение "go", которое вернет ссылку на функцию $parent.go. Затем он будет называться $parent.go(42). Недостатком этого шаблона является то, что вы получите ошибку, если выражение не будет оценивать функцию.
Последней причиной пониженного голосования было утверждение о том, что директивы ng-event используют &. Это не так. Ни одна из встроенных директив не создает изолированные области с помощью:
scope:{
}
Реализация "& foo" (упрощена для ясности), сводится к следующему:
$scope.foo = function(locals) {
return $parse(attr.foo)($scope.$parent, locals);
}
Реализация ng-click аналогична, но (также упрощена):
link: function(scope, elem, attr) {
elem.on('click', function(evt) {
$parse(attr.ngClick)(scope, {
$event: evt
}
});
}
Итак, ключом к запоминанию является то, что когда вы используете '&', вы не передаете функцию - вы передаете выражение. Директива может получить результат этого выражения в любое время, вызвав сгенерированную функцию.