带有原始绑定的指令中的函数回调

时间:2014-03-01 20:03:23

标签: javascript angularjs angularjs-directive angularjs-scope

将要在init上调用的函数传递给指令,此函数由字符串属性标记,然后对其进行解析和使用。问题是在使用时,函数绑定不再附加/绑定到函数所属的对象。这就是我的意思(see on plunker

<html ng-app="plunker">

<head>
<script data-require="angular.js@1.2.x" src="http://code.angularjs.org/1.2.13/angular.js" data-semver="1.2.13"></script>
<script>
var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.container = {
    x: null
  , setup: function(x){
      console.log(this); //this here should be $scope.container, but its window
      this.x = x;
    }
  };
});

app.directive('dir', ['$parse', function($parse) {
  return {
    restrict: 'E'
  , transclude: false
  , scope: true
  , link: function(scope, element, attrs) {
      var callback = attrs.setup
        , someCalcVar = 10
        ;
      $parse(callback)(scope)(someCalcVar);
    }
  };
}]);

</script>
</head>

<body ng-controller="MainCtrl">
  <p>container.x == '{{container.x}}'</p>
  <dir setup="container.setup"></dir>
</body>

</html>

有没有办法实现我想要的?也许有更好的方法来设计它,但仍然为回调和相关变量保留某种容器?

编辑:

天真的胜利可能是检查回调是否有dot,然后使用func.bind(substr(callback, ...))手动绑定...是否内置角度可以做到这一点?或者对所有这些都采取更清洁的方法吗?

4 个答案:

答案 0 :(得分:1)

这不是最优雅的解决方案,但你总是可以创建一个包装调用容器上的设置的函数:

$scope.callableSetup = function(x) {
    $scope.container.setup(x);  
}

答案 1 :(得分:1)

我发布one possible solution,使用underscorejs bind,我可以在控制器中强制执行此操作

$scope.container.setup = _.bind($scope.container.setup, $scope.container);

仍然不是我正在寻找的优雅,仍然在等待骑士的闪亮盔甲的答案

修改:guys over @goinstant有一个similar solution requiring underscore's bind technique but is more elegant

答案 2 :(得分:1)

尝试:

var that = this;
$scope.container = {
    x: null,
    setup: function(x) {
        console.log(that); //this here should be $scope.container, but its window
        console.log(x);
        that.x = x;
    }
};

答案 3 :(得分:1)

另一种可能的解决方案:

var self;
$scope.container = self = {
    x: null, 
    setup: function(x) {
        console.log(this);
        self.x = x;
    }
};

http://plnkr.co/edit/xtDWc5jyaayvTWgFrXaw?p=preview