Кажется, я не могу найти способ вызвать функцию в родительской области из директивы без использования изолированной области. Я знаю, что если я использую изолированную область видимости, я могу просто использовать «&» в изолированной области для доступа к функции в родительской области, но использование изолированной области, когда в этом нет необходимости, имеет последствия. Рассмотрим следующий HTML:
<button ng-hide="hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>
В этом простом примере я хочу показать диалоговое окно подтверждения JavaScript и вызывать doIt () только в том случае, если они нажимают «ОК» в диалоговом окне подтверждения. Это просто с использованием изолированного осциллографа. Директива будет выглядеть так:
.directive('confirm', function () {
return {
restrict: 'A',
scope: {
confirm: '@',
confirmAction: '&'
},
link: function (scope, element, attrs) {
element.bind('click', function (e) {
if (confirm(scope.confirm)) {
scope.confirmAction();
}
});
}
};
})
Но проблема в том, что поскольку я использую изолированную область видимости, ng-hide в приведенном выше примере больше не выполняется в родительской области , а скорее в изолированной области (поскольку использование изолированной области в любой директиве приводит к тому, что все директивы этого элемента будут использовать изолированную область). Вот jsFiddle из приведенного выше примера, где ng-hide не работает. (Обратите внимание, что в этой скрипке кнопка должна скрываться, когда вы вводите «да» в поле ввода.)
Альтернативой было бы НЕ использовать изолированную область видимости , чего я действительно хочу здесь, поскольку нет необходимости изолировать область действия этой директивы. Единственная проблема, с которой я столкнулся, заключается в том , как мне вызвать метод в родительской области, если я не передаю его в изолированной области ?
Вот jsfiddle, где я НЕ использую изолированную область видимости, а ng-hide работает нормально, но, конечно, вызов confirmAction () не работает, и я не знаю, как заставить его работать.
Обратите внимание, что я действительно ищу ответ, как вызывать функции во внешней области БЕЗ использования изолированной области. И я не заинтересован в том, чтобы этот диалог подтверждения работал по-другому, потому что суть этого вопроса состоит в том, чтобы выяснить, как выполнять вызовы во внешнюю область видимости и при этом иметь возможность работать с другими директивами против родительской области.
В качестве альтернативы мне было бы интересно услышать о решениях, использующих изолированную область видимости, если другие директивы по-прежнему будут работать против родительской области , но я не думаю, что это возможно.
источник
Ответы:
Поскольку директива вызывает только функцию (а не пытается установить значение свойства), вы можете использовать $ eval вместо $ parse (с неизолированной областью видимости):
Или, лучше, просто используйте $ apply , и $ eval () сопоставит свой аргумент с областью видимости:
Скрипка
источник
confirm-action="doIt(arg1)"
, а затем установитьscope.arg1
перед вызовом $ eval. Однако, вероятно, было бы чище использовать $ parse: stackoverflow.com/a/16200618/215945scope.$eval(attrs.confirmAction({arg1: 'blah'})
не пойдет. Вам нужно будет использовать $ parse с этим синтаксисом.Вы хотите использовать службу $ parse в AngularJS.
Итак, для вашего примера:
Есть одна хитрость, связанная с установкой свойства с помощью $ parse, но я позволю вам перейти через этот мост, когда вы подойдете к нему.
источник
scope:true
) не работает, потому что директива вообще не создает новую область видимости, и, таким образом,scope
свойство, на которое вы ссылаетесь вlink
функции, имеет ту же область видимости, что и ранее «родительская» область.Явно вызовите
hideButton
родительскую область видимости.Вот скрипка: http://jsfiddle.net/pXej2/5/
А вот обновленный HTML:
источник
Сначала небольшой момент: в этом случае область внешнего контроллера не является родительской областью области действия директивы; Объем внешнего контроллера является сферой Директивы. Другими словами, имена переменных, используемые в директиве, будут просматриваться непосредственно в области действия контроллера.
Затем запись
attrs.confirmAction()
не работает, потому чтоattrs.confirmAction
для этой кнопкиэто строка
"doIt()"
, и вы не можете вызвать строку, например"doIt()"()
.Ваш вопрос действительно таков:
В JavaScript вы в основном вызываете функции с использованием точечной записи, например:
Но вы также можете использовать обозначение массива:
Обратите внимание, как значение индекса является строкой . Итак, в своей директиве вы можете просто сделать это:
источник