繁体   English   中英

如何在自定义指令的隔离范围内的函数参数内公开模型?

[英]How can I expose models inside the function parameters that is in isolate scope of custom directive?

我想做什么

我想从我的范围方法访问该item ,如下面的示例

我尝试过的

标记

<span ng-repeat="item in items" on-whatever="handleWhatever(item)">
    {{item.name}}
</span>
<span ng-repeat="item in items" on-whatever="handleWhatever(item, $event)">
    {{item.name}}
</span>

调节器

app.controller('MyController', function($scope){
   $scope.items = [{name:'Item 1'}, {name: 'Item 2'}, ... ];
   $scope.handleWhatever = function(item, $event){
      console.log('This is the item that whatever happened on', item /*This is always undefined...*/);
      console.log('This is the $event that triggered the whatever', $event);
   };
});

指示

app.directive('onWhatever', function () {
    var linker = function (scope, element, attrs) {
        console.log(attrs);
        element.bind("whatever", function (event) {
            scope.$apply(function (){
                /*And here is my confusion... 
                  How do I access the function parameter here?
                  $event makes sense, but what about item?*/
                scope.onWhatever({'$event': evt});
            });
            evt.preventDefault();
        });
    };

    return {
        link: linker,
        scope:{
            onWhatever: '&'
        }
    }
});

我知道这是有可能的,因为这就是ng-click这样的本地指令的工作方式,但是我似乎无法在角度源代码中找到指令定义...

以下代码在循环中创建了多个指令

forEach(
      'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),

从angularjs源代码

/*
 * A collection of directives that allows creation of custom event handlers that are defined as
 * angular expressions and are compiled and executed within the current scope.
 */
var ngEventDirectives = {};

// For events that might fire synchronously during DOM manipulation
// we need to execute their event handlers asynchronously using $evalAsync,
// so that they are not executed in an inconsistent state.
var forceAsyncEvents = {
  'blur': true,
  'focus': true
};
forEach(
  'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
  function(eventName) {
    var directiveName = directiveNormalize('ng-' + eventName);
    ngEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) {
      return {
        restrict: 'A',
        compile: function($element, attr) {
          // We expose the powerful $event object on the scope that provides access to the Window,
          // etc. that isn't protected by the fast paths in $parse.  We explicitly request better
          // checks at the cost of speed since event handler expressions are not executed as
          // frequently as regular change detection.
          var fn = $parse(attr[directiveName], /* interceptorFn */ null, /* expensiveChecks */ true);
          return function ngEventHandler(scope, element) {
            element.on(eventName, function(event) {
              var callback = function() {
                fn(scope, {$event:event});
              };
              if (forceAsyncEvents[eventName] && $rootScope.$$phase) {
                scope.$evalAsync(callback);
              } else {
                scope.$apply(callback);
              }
            });
          };
        }
      };
    }];
  }
);

在得到maurycy的帮助后,我弄清楚了我错了。

这是可以访问传递给传递函数的参数的最简单的指令:

app.directive('onWhatever',function($parse, $rootScope) {
      return {
        // Notice how we DON'T create an isolate scope. Doing so
        // will cause our handler to never actually get access
        // to the properties we need
        restrict: 'A',
        compile: function($element, attr) {
          // This fn function that is returned by $parse
          // is actually the same thing as using 
          // scope: {onWhatever: '&'}, but it also
          // takes all passed arguments into account
          var fn = $parse(attr.onWhatever, null, true);
          return function (scope, element) {
            element.on('whatever', function(event) {
              var callback = function() {
                fn(scope, {$event:event});
              };
              scope.$apply(callback);
            });
          };
        }
      };
    });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM