我正在创建一个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
链接时,我无法显示对话框。
我试图通过单独点击按钮来打开对话框,但它确实有效。需要帮助!
答案 0 :(得分:1)
由于你的指令有一个isolated scope(参见隔离指令的范围),我可以告诉它,因为它的声明包含scope: {...}
,该指令将限制项目在范围上只有你的指令定义。
指令可以从父作用域继承项目,甚至可以使用与父作用域相同的作用域,但在这种情况下它不会。
如果您有一个独立的范围,那么在该范围内定义项目的唯一方法是将它们放在控制器link
函数中,或者将它们定义为范围选项你的指示。现在,如果getRulesTest()
仅特定于您的指令(不能在其外部重复使用,未在父控制器上定义等),那么只需在您的link
函数(或指令&#39; s控制器,如果它有一个,无论什么有意义):
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
声明中添加了范围选项。现在,您的父控制器将在要绑定的范围上添加一个函数:
.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})"
Here is a plunk有一个工作示例。
我在原始答案中遇到了一个关于如何调用函数范围选项的小错误。有几种方法可以调用绑定的函数,具体取决于您是否有参数以及匹配方式。这部分有点令人困惑。如果您没有关注,只需坚持选项#2。
假设您希望他们简单地说明(请注意,我们只提供规则的名称,没有括号或参数名称):
<div class="rules-directive" ... rules-test="doSomethingWithRules">
然后你的指令应该调用这样的函数(注意我们调用一个裸函数,它生成一个可以用来实际调用函数的调用者,然后然后我们用实际调用它参数):
ng-click="getRulesTest()(rules)"
如果您有多个参数,最好说明这一点。假设该指令提供了两个参数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是首选,因为它为您的指令的消费者提供了更大的灵活性,并且省去了必须记住参数提供给您的函数的顺序的麻烦。