我的指令中有一个更新模型函数,我想从控制器调用它。如何从控制器访问指令功能?我可以调用模型更改,但为此我必须执行click事件。
以下是我的代码:
<div ng-if="((individualDropdown && YesRadio) || FolderDropdown)">
<searchable-multiselect display-attr="infoMarketCodeWithName"
selected-items="formData.market"
all-items="allMarkets"
add-item="addMarketToList(item,allMarkets)"
remove-item="removeMarketFromList(item,allMarkets)"
ng-disable="NoRadio || NotSureRadio"
ng-model="formData.market" name="marketDropdown">
</searchable-multiselect>
</div>
指令代码和要调用的函数是updateSelectedItems
app.directive("searchableMultiselect", ['$timeout', '$filter', function($timeout, $filter) {
return {
templateUrl: "Templates/SearchableMultiselect.html",
require: 'ngModel',
restrict: "AE",
scope: {
displayAttr: "@", //one way binding & only expression
selectedItems: "=", //two way binding & expects model name
allItems: "=",
readOnly: "=",
addItem: "&",
removeItem: "&", //method binding
},
link: function(scope, element, attrs) {
element.bind('click', function(event) {
event.stopPropagation();
});
scope.updateSelectedItems = function(obj) {
console.log(scope.allMarkets);
//code goes here
}
}
])
答案 0 :(得分:1)
从AngularJS良好实践的角度来看,你应该强制执行关注点分离原则,不要对控制器施加如此强烈的依赖性,以便知道指令中的函数名称等。
一种替代方法是使用事件驱动的方法,其中指令提交一个事件,由受控制的事件捕获并通过更新模型来关闭周期。
app.directive("searchableMultiselect", ['$timeout', '$filter', function($timeout, $filter) {
return {
templateUrl: "Templates/SearchableMultiselect.html",
require: 'ngModel',
restrict: "AE",
scope: {
displayAttr: "@", //one way binding & only expression
selectedItems: "=", //two way binding & expects model name
allItems: "=",
readOnly: "=",
addItem: "&",
removeItem: "&", //method binding
},
link: function(scope, element, attrs) {
element.bind('click', function(event) {
event.stopPropagation();
});
scope.updateSelectedItems = function(obj) {
console.log(scope.allMarkets);
scope.$emit("updateSelectedItems", scope.allMarkets);
}
}
}
}])
在控制器中:
app.controller("ctrl", ['$scope', function ($scope) {
$scope.$on("updateSelectedItems", function (event, allMarkets) {
// Do stuff with data
// Update data model bound to directive if necessary
});
}])
希望这是有道理的:)
答案 1 :(得分:-1)
当指令使用ngModelController
时,selected-items
属性是多余的:
<div ng-if="((individualDropdown && YesRadio) || FolderDropdown)">
<searchable-multiselect
display-attr="infoMarketCodeWithName"
̶s̶e̶l̶e̶c̶t̶e̶d̶-̶i̶t̶e̶m̶s̶=̶"̶f̶o̶r̶m̶D̶a̶t̶a̶.̶m̶a̶r̶k̶e̶t̶"̶
ng-model="formData.market"
all-items="allMarkets"
add-item="addMarketToList(item,allMarkets)"
remove-item="removeMarketFromList(item,allMarkets)"
read-only="NoRadio || NotSureRadio"
name="marketDropdown">
</searchable-multiselect>
</div>
使用$setViewValue
方法设置所选值:
require: 'ngModel',
restrict: "E",
scope: {
displayAttr: "@", //one way binding & only expression
̶s̶e̶l̶e̶c̶t̶e̶d̶I̶t̶e̶m̶s̶:̶ ̶"̶=̶"̶,̶ ̶/̶/̶t̶w̶o̶ ̶w̶a̶y̶ ̶b̶i̶n̶d̶i̶n̶g̶ ̶&̶ ̶e̶x̶p̶e̶c̶t̶s̶ ̶m̶o̶d̶e̶l̶ ̶n̶a̶m̶e̶
ngModel: "<",
allItems: "<",
addItem: "&",
removeItem: "&", //method binding
readOnly: "<",
},
̶l̶i̶n̶k̶:̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶(̶s̶c̶o̶p̶e̶,̶ ̶e̶l̶e̶m̶e̶n̶t̶,̶ ̶a̶t̶t̶r̶s̶)̶ ̶{̶
link: function(scope, element, attrs, ngModel) {
element.bind('click', function(event) {
event.stopPropagation();
});
scope.updateSelectedItems = function(obj) {
console.log(scope.allMarkets);
//code goes here
ngModel.$setViewValue(obj);
}
}
有关详细信息,请参阅