angularjs directive call function specified in attribute and pass an argument to it

后端 未结 7 745
难免孤独
难免孤独 2020-12-22 17:11

I want to create a directive that links to an attribute. The attribute specifies the function that should be called on the scope. But I also want to pass an argument to the

相关标签:
7条回答
  • 2020-12-22 17:42

    Not knowing exactly what you want to do... but still here's a possible solution.

    Create a scope with a '&'-property in the local scope. It "provides a way to execute an expression in the context of the parent scope" (see the directive documentation for details).

    I also noticed that you used a shorthand linking function and shoved in object attributes in there. You can't do that. It is more clear (imho) to just return the directive-definition object. See my code below.

    Here's a code sample and a fiddle.

    <div ng-app="myApp">
    <div ng-controller="myController">
        <div my-method='theMethodToBeCalled'>Click me</div>
    </div>
    </div>
    
    <script>
    
       var app = angular.module('myApp',[]);
    
       app.directive("myMethod",function($parse) {
           var directiveDefinitionObject = {
             restrict: 'A',
             scope: { method:'&myMethod' },
             link: function(scope,element,attrs) {
                var expressionHandler = scope.method();
                var id = "123";
    
                $(element).click(function( e, rowid ) {
                   expressionHandler(id);
                });
             }
           };
           return directiveDefinitionObject;
       });
    
       app.controller("myController",function($scope) {
          $scope.theMethodToBeCalled = function(id) { 
              alert(id); 
          };
       });
    
    </script>
    
    0 讨论(0)
  • 2020-12-22 17:46

    Here's what worked for me.

    Html using the directive

     <tr orderitemdirective remove="vm.removeOrderItem(orderItem)" order-item="orderitem"></tr>
    

    Html of the directive: orderitem.directive.html

    <md-button type="submit" ng-click="remove({orderItem:orderItem})">
           (...)
    </md-button>
    

    Directive's scope:

    scope: {
        orderItem: '=',
        remove: "&",
    
    0 讨论(0)
  • 2020-12-22 17:46

    My solution:

    1. on polymer raise an event (eg. complete)
    2. define a directive linking the event to control function

    Directive

    /*global define */
    define(['angular', './my-module'], function(angular, directives) {
        'use strict';
        directives.directive('polimerBinding', ['$compile', function($compile) {
    
                return {
                     restrict: 'A',
                    scope: { 
                        method:'&polimerBinding'
                    },
                    link : function(scope, element, attrs) {
                        var el = element[0];
                        var expressionHandler = scope.method();
                        var siemEvent = attrs['polimerEvent'];
                        if (!siemEvent) {
                            siemEvent = 'complete';
                        }
                        el.addEventListener(siemEvent, function (e, options) {
                            expressionHandler(e.detail);
                        })
                    }
                };
            }]);
    });
    

    Polymer component

    <dom-module id="search">
    
    <template>
    <h3>Search</h3>
    <div class="input-group">
    
        <textarea placeholder="search by expression (eg. temperature>100)"
            rows="10" cols="100" value="{{text::input}}"></textarea>
        <p>
            <button id="button" class="btn input-group__addon">Search</button>
        </p>
    </div>
    </template>
    
     <script>
      Polymer({
        is: 'search',
                properties: {
          text: {
            type: String,
            notify: true
          },
    
        },
        regularSearch: function(e) {
          console.log(this.range);
          this.fire('complete', {'text': this.text});
        },
        listeners: {
            'button.click': 'regularSearch',
        }
      });
    </script>
    
    </dom-module>
    

    Page

     <search id="search" polimer-binding="searchData"
     siem-event="complete" range="{{range}}"></siem-search>
    

    searchData is the control function

    $scope.searchData = function(searchObject) {
                        alert('searchData '+ searchObject.text + ' ' + searchObject.range);
    
    }
    
    0 讨论(0)
  • 2020-12-22 17:48

    Marko's solution works well.

    To contrast with recommended Angular way (as shown by treeface's plunkr) is to use a callback expression which does not require defining the expressionHandler. In marko's example change:

    In template

    <div my-method="theMethodToBeCalled(myParam)"></div>
    

    In directive link function

    $(element).click(function( e, rowid ) {
      scope.method({myParam: id});
    });
    

    This does have one disadvantage compared to marko's solution - on first load theMethodToBeCalled function will be invoked with myParam === undefined.

    A working exampe can be found at @treeface Plunker

    0 讨论(0)
  • 2020-12-22 17:53

    You can create a directive that executes a function call with params by using the attrName: "&" to reference the expression in the outer scope.

    We want to replace the ng-click directive with ng-click-x:

    <button ng-click-x="add(a,b)">Add</button>
    

    If we had this scope:

    $scope.a = 2;
    $scope.b = 2;
    
    $scope.add = function (a, b) {
      $scope.result = parseFloat(a) + parseFloat(b);
    }
    

    We could write our directive like so:

    angular.module("ng-click-x", [])
    
    .directive('ngClickX', [function () {
    
      return {
    
        scope: {
    
          // Reference the outer scope
          fn: "&ngClickX",
    
        },
    
        restrict: "A",
    
        link: function(scope, elem) {
    
          function callFn () {
            scope.$apply(scope.fn());
          }
    
          elem[0].addEventListener('click', callFn);
        }
      };
    }]);
    

    Here is a live demo: http://plnkr.co/edit/4QOGLD?p=info

    0 讨论(0)
  • 2020-12-22 17:55

    This should work.

    <div my-method='theMethodToBeCalled'></div>
    
    app.directive("myMethod",function($parse) {
      restrict:'A',
      scope: {theMethodToBeCalled: "="}
      link:function(scope,element,attrs) {
         $(element).on('theEvent',function( e, rowid ) {
            id = // some function called to determine id based on rowid
            scope.theMethodToBeCalled(id);
         }
      }
    }
    
    app.controller("myController",function($scope) {
       $scope.theMethodToBeCalled = function(id) { alert(id); };
    }
    
    0 讨论(0)
提交回复
热议问题