AngularJS ng-click не работает в ng-grid
-
21-12-2019 - |
Вопрос
Я создаю приложение ASP.net MVC, и в нем я отображаю ng-grid со столбцом, в котором ссылка указана в качестве содержимого ячейки.
Вот как я этого добился.
Контроллер (ng-grid):
columnDefs: [
{ field: 'FreightRules', visible: true,
cellTemplate:
'<div class="rulesDirective" freight-rules="{{row.entity.FreightItemGuid}}">
</div>',
enableCellEdit: false, enableCellSelection: false }]
Директива:
directives.directive('rulesDirective', function () {
return {
restrict: 'C',
replace: true,
transclude: true,
scope: { freightRules: '@freightRules' },
template: '<div ng-switch on="freightRules | areRulesAvailable">' +
'<div ng-switch-when = true><a ng-click="getRulesTest(\'{{freightRules}}\')" href="#addFreightRuleModal">Rules</a></div>' +
'<div ng-switch-when = false>No Rules</div>' +
'<div ng-switch-default class="grid">Error</div>' +
'</div>'
}});
Фильтр:
filters.filter('areRulesAvailable', function () {
return function (value) {
if (value != '00000000-0000-0000-0000-000000000000') {
result= true;
}
else {
result = false;
}
return result;
};
});
Это работает нормально, но когда я нажимаю на Rules
ссылка Я не могу отобразить диалоговое окно.
Я попытался открыть диалоговое окно, нажав на кнопку отдельно, и это сработало.Нужна помощь!
Решение
Поскольку ваша директива содержит изолированная область применения (см . Определение сферы применения Директивы), о котором я могу судить, потому что его объявление содержит scope: {...}
, директива ограничит элементы области видимости только тем, что определяет ваша директива.
Директивы могут наследовать элементы из родительской области или даже использовать ту же область, что и родительская, но в данном случае этого не произойдет.
Когда у вас есть изолированная область, единственный способ определить элементы в этой области - поместить их туда в контроллере, link
функции, или определите их как параметр области применения в рамках ваших указаний.Теперь, если getRulesTest()
специфичен только для вашей директивы (не может использоваться повторно вне ее, не определен на родительском контроллере и т.д.), Тогда просто определите его в вашем link
функция (или контроллер директивы, если он у нее есть, в зависимости от того, что имеет смысл):
directives.directive('rulesDirective', function () {
return {
restrict: 'C',
replace: true,
transclude: true,
scope: { freightRules: '@freightRules' },
link: function($scope) { // looky here
$scope.getRulesTest = function() {
console.log('check me out');
};
},
template: '<div ng-switch on="freightRules | areRulesAvailable">' +
'<div ng-switch-when = true><a ng-click="getRulesTest(freightRules)" href="#addFreightRuleModal">Rules</a></div>' +
'<div ng-switch-when = false>No Rules</div>' +
'<div ng-switch-default class="grid">Error</div>' +
'</div>'
}});
Поскольку вы нигде в своем примере не определяете его в пределах области действия директивы, я предполагаю, что вы объявляете его на родительском контроллере и думаете, что он должен просто вызвать из области действия директивы и найти его в родительской области.Как я уже сказал выше, это не сработает.Вы можете использовать параметр области видимости, который привязывается к функции с помощью &
синтаксис.Это позволяет вашему представлению декларативно назначать функцию из родительской области для вашей директивы, чтобы использовать ее при вызове.
directives.directive('rulesDirective', function() {
return {
restrict: 'C',
replace: true,
transclude: true,
scope: {
freightRules: '=',
getRulesTest: '&rulesTest' // <- this guy. the text on the left is what you want the item named on the scope locally. the text on the right, after the & is what the attribute on the element should be called. if you want them to be the same on both sides, simply enter '&'
},
template: '<div ng-switch on="freightRules | areRulesAvailable">' +
'<div ng-switch-when="true"><a ng-click="getRulesTest({rules: freightRules})" href="">Rules</a></div>' +
'<div ng-switch-when="false">No Rules</div>' +
'<div ng-switch-default class="grid">Error</div>' +
'</div>'
};
})
Мы добавили опцию scope в ваш scope
декларация.Теперь ваш родительский контроллер добавит функцию в область, к которой будет привязана:
.controller('MyCtrl', function($scope) {
$scope.doSomethingWithRules = function(rules) {
console.log('sup?');
};
});
И вид из окна выглядел бы так:
<div class="rules-directive" rules-test="doSomethingWithRules(rules)"></div>
Другая вещь, которая может быть проблематичной, - это то, что вы делаете с этой строкой в шаблоне:
ng-click="getRulesTest(\'{{freightRules}}\')"
Вы пытаетесь передать этой функции вычисленный строковый результат {{freightRules}}
(что кажется не очень полезным), или вы хотите передать это в реальном freightRules
объект (который кажется более вероятным)?Если это так, просто измените его на:
ng-click="getRulesTest({rules: freightRules})"
Редактировать
Вот такой плюх с рабочим примером.
Я действительно обнаружил небольшую ошибку в своем первоначальном ответе о том, как вызвать параметры области видимости функции.Есть несколько способов вызвать функции, которые вы привязали, в зависимости от того, есть ли у вас параметры и как вы хотите, чтобы они соответствовали.Эта часть немного сбивает с толку.Если вы не понимаете, просто придерживайтесь варианта № 2.
1.Вы хотите просто передать Имя функции, которую она должна вызвать, с параметрами, определенными обычным образом.
Допустим, вы хотите, чтобы они просто указывали (обратите внимание, что мы указываем только название правил, без скобок или имен параметров):
<div class="rules-directive" ... rules-test="doSomethingWithRules">
Затем ваша директива должна вызывать функцию следующим образом (обратите внимание, что мы вызываем голую функцию, которая генерирует вызывающее средство, которое может использоваться для фактического вызова функции, и тогда мы вызываем его с фактическими параметрами):
ng-click="getRulesTest()(rules)"
2.Вы хотите, чтобы вызывающий передавал именованные аргументы, чтобы вы могли изменить порядок параметров или опустить их.
Это лучше всего проиллюстрировано, если у вас есть несколько параметров.Допустим, директива предоставляет два параметра, paramA
и paramB
.Вы вызываете функцию в своей директиве, используя объект, содержащий имена и значения параметров.
ng-click="getRulesTest({paramA: valuesForA, paramB: valuesForB })"
Затем, при использовании директивы, ваша разметка выглядит следующим образом:
<div class="rules-directive" ... rules-test="doSomethingWithRules(paramA, paramB)">
Причина, по которой это предпочтительнее, заключается в ситуации, когда вы хотите изменить порядок или опустить параметр в вызываемой функции.Допустим, doSomethingWithRules
только потребности paramB
.Теперь я могу это сделать:
<div class="rules-directive" ... rules-test="doSomethingWithRules(paramB)">
Я не смог бы сделать этого с опцией # 1 выше, потому что она всегда вызывается со всеми параметрами обычным образом.Итак, вариант № 2 предпочтительнее, потому что он дает потребителям вашей директивы больше гибкости и избавляет их от необходимости запоминать, в каком порядке параметры передаются в вашу функцию.