我有一个创建多个表单元素的指令:
// Directive
app.directive('comboInput', function(){
return {
scope: {
imodel: '=',
dmodel: '=',
bmodel: '=',
inputname: '@',
integers: '=',
decimals: '='
},
templateUrl: templatePath + 'combo-input.html'
}
});
// Template
<select id="" ng-model="imodel" ng-change="bmodel=imodel+dmodel" ng-options="value for value in integers"></select>
<select id="" ng-model="dmodel" ng-change="bmodel=imodel+dmodel" ng-options="(value|fraction) for value in decimals"></select>
<input type="number" name="{{inputname}}" ng-model="bmodel">
// Usage
<combo-input inputname="width" bmodel="width" imodel="widthI" dmodel="widthD" integers="ints" decimals="decs"></combo-input>
此应用程序的控制器有一种获取价格的方法:
$scope.getProductPrice = function(){
return $http.post('/customize/angular/getProductPrice', {
sku: '$scope.sku',
width: $scope.width,
height: $scope.height
}).then(function(response){
$scope.productPrice = parseFloat(response.data).toFixed(2);
});
}
我在表单的各个部分使用此方法,通常通过在某个表单元素上调用ng-change="getProductPrice()"
;但是,从模板中调用它时,这不起作用。
我已经在SO上找到了许多不同的答案,但是没有一个像预期的那样工作(比如永远运行的无限$ http电话),或者如果他们这样做,提交答案的人提供的不是关于为什么代码的评论或其他详细信息,因此我无法适应我的需求。除此之外,各种方法都使用不同的技术,有些方法已被弃用,因此找出我需要做的事情没有一致性。
如何从我的指令模板中调用getProductPrice()
?
修改
我创建了一个Plunker来演示传递给getProductPrice()
方法的旧值。
答案 0 :(得分:1)
您的指令具有隔离范围(scope: {...}
),因此它无法访问上层控制器范围的变量和方法,例如getProductPrice
。
您可以做的是将此方法作为参数传递给您的指令:
app.directive('comboInput', function () {
return {
scope: {
imodel: '=',
dmodel: '=',
bmodel: '=',
inputname: '@',
integers: '=',
decimals: '=',
on-change: '&'
},
templateUrl: templatePath + 'combo-input.html'
}
});
然后你会像这样实现:
<combo-input ... on-change="getProductPrice()"></combo-input>
然后你只需要从你的指令中调用scope.onChange()
来调用已经绑定到on-change
属性的这个函数。
或者您甚至可以直接将其绑定到内置ng-change
:
<input ... ng-change="onChange()">
更新:如果您要为此调用传递特定参数,只需将其添加到方法签名中即可:
$scope.getProductPrice = function(width, height) { ... }
并且还在指令绑定中:
<combo-input ... on-change="getProductPrice(width, height)"></combo-input>
然后您需要做的就是使用这些参数调用onChange
。如果您在HTML中编写它,它就像:
<input ng-change="onChange(width, height)">
(确保width
和height
明显在您的指令范围内,以便可以在HTML中使用。
如果您想从代码中调用该代码,则width
和height
已经在您的范围内,在这种情况下,您只需要致电scope.onChange()
。但是,如果不是,则可以使用以下特定语法为此调用添加这些参数:
scope.onChange({width: value1, height:value2})
另一种方法是使这个Ajax方法成为服务而不是控制器功能。通过在您的指令中注入服务,您可以直接调用myService.getProductPrice()
。参数绑定的优点是您可以使用不同的行为重用您的指令,但如果它总是调用该函数,那么首选服务。
答案 1 :(得分:0)
由于您将指令的范围声明为新指令,因此您声明的条目将绑定在此范围与外部(使用其中的方法)之间。
您可以使用指令定义对象的scope散列将函数传递给指令作用域,也可以在指令中添加另一个具有相同控制器的ng-controller。