如何在angularJS中从控制器调用指令函数?

时间:2018-06-05 13:23:55

标签: angularjs angularjs-directive angularjs-controller

我的指令中有一个更新模型函数,我想从控制器调用它。如何从控制器访问指令功能?我可以调用模型更改,但为此我必须执行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
            }
          }
        ])

2 个答案:

答案 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);
        }
    }

有关详细信息,请参阅