【问题标题】:How to call directive function from controller in angularJS?如何在angularJS中从控制器调用指令函数?
【发布时间】:2018-06-05 13:23:55
【问题描述】:

我的指令中有一个更新模型函数,我想从控制器调用它。如何从控制器访问指令功能?我可以调用模型更改,但为此我必须执行点击事件。

下面是我的代码:

<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
            }
          }
        ])

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-controller


    【解决方案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
        });
    }])
    

    希望这是有道理的:)

    【讨论】:

      【解决方案2】:

      当指令使用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);
              }
          }
      

      有关详细信息,请参阅

      【讨论】:

        猜你喜欢
        • 2021-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-29
        • 2018-01-03
        • 1970-01-01
        相关资源
        最近更新 更多