AngularJS - 将函数传递给指令

use*_*026 156 angularjs

我有一个例子angularJS

<div ng-controller="testCtrl">

<test color1="color1" updateFn="updateFn()"></test>
</div>
 <script>
  angular.module('dr', [])
.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function() {
        alert('123');
    }
})
.directive('test', function() {
    return {
        restrict: 'E',
        scope: {color1: '=',
                updateFn: '&'},
        template: "<button ng-click='updateFn()'>Click</button>",
        replace: true,
        link: function(scope, elm, attrs) { 
        }
    }
});

</script>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

我想当我点击按钮时,会出现警告框,但没有任何显示.

谁能帮我?

Alw*_*ner 239

要从隔离范围指令内部调用父作用域中的控制器函数,请使用dash-separatedHTML中的属性名称,如OP所述.

此外,如果要向函数发送参数,请通过传递对象来调用该函数:

<test color1="color1" update-fn="updateFn(msg)"></test>
Run Code Online (Sandbox Code Playgroud)

JS

var app = angular.module('dr', []);

app.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function(msg) {        
        alert(msg);
    }
});

app.directive('test', function() {
    return {
        restrict: 'E',
        scope: {
            color1: '=',
            updateFn: '&'
        },
        // object is passed while making the call
        template: "<button ng-click='updateFn({msg : \"Hello World!\"})'>
            Click</button>",
        replace: true,        
        link: function(scope, elm, attrs) {             
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

Fiddle

  • 效果很好.耻辱OP不投票或接受答案. (9认同)
  • 由于某种原因,这个论点对我来说是不确定的. (8认同)
  • AngularJS中不推荐使用`replace`属性:/sf/ask/1693648071/ (2认同)
  • 对象映射 ```updateFn({msg: 'my message'});``` 在指令的 ```link``` 函数中进行函数调用时,必须以该格式使用。 (2认同)

ste*_*eve 155

也许我遗漏了一些东西,但是虽然其他解决方案确实调用了父范围函数,但是没有能力从指令代码传递参数,这是因为例如使用固定参数update-fn调用.稍微改变允许指令传递参数,我认为这更有用.updateFn(){msg: "Hello World"}

<test color1="color1" update-fn="updateFn"></test>
Run Code Online (Sandbox Code Playgroud)

请注意,HTML正在传递函数引用,即没有()括号.

JS

var app = angular.module('dr', []);

app.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function(msg) {        
        alert(msg);
    }
});

app.directive('test', function() {
    return {
        restrict: 'E',
        scope: {
            color1: '=',
            updateFn: '&'
        },
        // object is passed while making the call
        template: "<button ng-click='callUpdate()'>
            Click</button>",
        replace: true,        
        link: function(scope, elm, attrs) {       
          scope.callUpdate = function() {
            scope.updateFn()("Directive Args");
          }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

所以在上面,HTML调用本地作用域callUpdate函数,然后从父作用域"获取"updateFn并使用指令可以生成的参数调用返回的函数.

http://jsfiddle.net/mygknek2/

  • @Ludwik11肯定 - 因为scope.updateFn在定义时是这样的函数返回一个函数(因此是()())这是因为我们传入范围(通过html中的update-fn ="updateFn")引用到我们想要的函数.第一个()是对angular的调用以返回此引用,2nd()调用我们的函数,并且是我们传递任何参数的地方.HTH (10认同)
  • 不知道我怎么能得到一个有效的东西投票?如果要进行投票,你应该发表评论. (8认同)
  • 这对我有用.如果你不想要额外的功能只需写'ng-click ="updateFn()('Directive Args')"` (7认同)
  • 哇!scope.updateFn()("指令Args"); !NOT scope.updateFn("Directive Args"); ! (7认同)
  • 这确实是更完美的答案!! (2认同)
  • 请注意,上述解决方案会更改此范围。因此,例如,如果您使用`controllerAs`,并且正在将包含`this.something`的函数传递到指令中-那么从指令中调用它将无法正常工作。 (2认同)

Ofe*_*gev 38

在'test'指令Html标记中,函数的属性名称不应该是camelCased,而是基于破折号.

所以 - 而不是:

<test color1="color1" updateFn="updateFn()"></test>
Run Code Online (Sandbox Code Playgroud)

写:

<test color1="color1" update-fn="updateFn()"></test>
Run Code Online (Sandbox Code Playgroud)

这是angular的方式来区分指令属性(例如update-fn函数)和函数之间的区别.


Már*_*más 8

如何通过双向绑定传递控制器功能?然后你可以在指令中使用它,就像在常规模板中一样(为了简单起见,我剥离了不相关的部分):

<div ng-controller="testCtrl">

   <!-- pass the function with no arguments -->
   <test color1="color1" update-fn="updateFn"></test>
</div>

<script>
   angular.module('dr', [])
   .controller("testCtrl", function($scope) {
      $scope.updateFn = function(msg) {
         alert(msg);
      }
   })
   .directive('test', function() {
      return {
         scope: {
            updateFn: '=' // '=' bidirectional binding
         },
         template: "<button ng-click='updateFn(1337)'>Click</button>"
      }
   });
</script>
Run Code Online (Sandbox Code Playgroud)

我降落在这个问题,因为我尝试了上面的方法befire,但不知怎的,它没有用.现在它完美无缺.


小智 5

使用破折号和小写字母表示属性名称(就像说的其他答案一样):

 <test color1="color1" update-fn="updateFn()"></test>
Run Code Online (Sandbox Code Playgroud)

并在指令范围内使用“ =”代替“&”:

 scope: { updateFn: '='}
Run Code Online (Sandbox Code Playgroud)

然后,您可以像其他任何函数一样使用updateFn:

 <button ng-click='updateFn()'>Click</button>
Run Code Online (Sandbox Code Playgroud)

你去!

  • 为什么要使用'='而不是'&'?当我尝试这样做时,它会不断重复调用我的函数。 (5认同)
  • 为此使用“ =”是错误的。那是两种方式的对象绑定。 (2认同)
  • 不好回答。很坏。 (2认同)