通过指令传递对象

时间:2015-03-19 21:14:06

标签: angularjs directive

这似乎已被问过千种不同的方式,但从来没有像我一样,所以这里是我的(请原谅我,如果已经在SO上有答案):

基本上我希望通过自定义指令传递一个对象,以便由函数进行评估。

HTML:

<div ng-controller="app">
    <div ng-touchstart="process_person(person)" ng-repeat="person in people">{{person.name}}</div>
</div>

角:

var myApp = angular.module("myApp", []);

myApp.controller('app',function(){
    $scope.people = [{name:'bob','id':49},{name:'al','id':50}];
    $scope.process_person = function(person){
        console.log('processing: ' + person.id);
        // result is person is undefined
    }
});

(来自https://github.com/marktopper/ngTouchstart

myApp.directive("ngTouchstart", function () {
  return {
    controller: function ($scope, $element, $attrs) {
      $element.bind('touchstart', onTouchStart);
      function onTouchStart(event) {
        var method = '$scope.' + $element.attr('ng-touchstart');
        $scope.$apply(function () {
          eval(method);
        });
      };
    }
  };
});

我知道该指令将属性数据作为字符串进行评估,我想知道如何纠正上述指令以传递我的对象,以便我可以在我的控制器中处理它。

2 个答案:

答案 0 :(得分:0)

最简单的方法是,如果你负担得起,就是用"&"创建一个隔离范围:

.directive("ngTouchstart", function(){
  return {
    scope: {
      onStart: "&ngTouchstart"
    },
    link: function(scope){
      //...
      function onTouchStart(event) {
        scope.onStart();
      }
    }
  }
});

由于创建隔离区或子作用域并非没有成本(同一元素上没有其他指令可以创建另一个作用域),那么您可以使用$parse服务:

link: function(scope, element, attrs){
  var onStart = $parse(attrs.ngTouchstart);

  function onTouchStart(event){
    onStart(scope);
  }
}

plunker

答案 1 :(得分:0)

我将您的控制器代码复制并粘贴到一个小提琴中,我不断收到此错误:

  

$ scope未定义

我没有费心去检查哪条线正在扔它,因为它显示在Angular内部发生。但是,我终于注意到了一些事情:$scope没有传递到你的控制器构造函数中(至少在这里显示的例子中没有)。事情开始起作用了。我还使用$scope.$eval(method)代替$scope.$apply( ... eval(method) ... )。最后,我在onTouchStart调用之前放置了bind函数的定义,但这不重要。以下是完整的示例:

myApp.controller('app',function($scope){
    $scope.people = [{name:'bob','id':49},{name:'al','id':50}];
    $scope.process_person = function(person){
        console.log('processing: ' + person.id);
        return person;
    }
});

myApp.directive("ngTouchstart", function () {
  return {
    controller: function ($scope, $element, $attrs) {
      function onTouchStart(event) {
        var method = $attrs['ng-touchstart'];
        $scope.$eval(method);
      };
      $element.bind('touchstart', onTouchStart);
    }
  };
});

Here is that fiddle I mentioned