【问题标题】:bind callback to directive without isolated scope将回调绑定到没有隔离范围的指令
【发布时间】:2016-04-28 11:03:39
【问题描述】:

将回调函数绑定到指令时,使用正确的上下文执行此函数对我来说很重要。现在,只要指令有一个孤立的范围,它就不是问题

<bar-foo callback="mycontroller.callback()"></bar-foo>

和指令:

 ...
 scope:{
     callback: '&'
 },
 ...

在没有隔离作用域的情况下,我从 $attrs 属性中提取回调

$scope.callback = $parse($attrs.callback)($scope);

但是,现在我做不到

 <bar-foo callback="mycontroller.callback()"></bar-foo>

因为它会直接执行回调。解决这个问题的首选方法是什么?

DEMO

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    首先在您的控制器中创建一个函数,该函数在此函数内部显式设置this 的值:

    this.exportableCallback = this.callback.bind(this);
    

    其中this.callback 是您用于隔离作用域的那个。

    第二步是设置属性

    <hello-world callback="mycontroller.exportableCallback"></hello-world>
    

    不要像在隔离范围内那样调用函数。

    fiddle

    另一个选项(如果您从控制器中删除 this.callback)是

    this.exportableCallback = function() {
      console.log(this.test);
    }.bind(this);
    

    如果你想给这个函数传递参数:

    this.exportableCallback = function() {
      console.log(arguments);
    }.bind(this);
    

    【讨论】:

    • 我确实看到了这个答案 :) 但我希望得到类似于孤立范围的情况。谢谢!
    • @JeanlucaScaljeri 隔离范围做类似的事情 :) 他们只是把它从我们的眼睛里隐藏起来
    【解决方案2】:

    由于这个作用域不是孤立的,不只是调用你想要的吗?

        .directive('helloWorld', function () {
        return {
            restrict: 'E',
            template: '<button ng-click="mycontroller.callback()">Not isolated</button>',
        }
    });
    

    然后只是调用你的指令?

    <hello-world></hello-world>
    

    或者我在这里遗漏了什么?使用 require 属性指定控制器也是可取的。

    【讨论】:

    • 如果要重用指令怎么办?
    • 您必须确保控制器在需要时可用,但我不会真正推荐这种做事方式。这是一个例子来回答这个例子。在我看来,最好有自己的控制器并以隔离的方式调用事物,这样就可以重用了。
    【解决方案3】:

    在没有范围的指令中,只需访问指令模板中的mycontroller.callback()

    .directive('helloWorld', function () {
        return {
            restrict: 'E',
            scope: false,
            //Use THIS
            template: '<button ng-click="mycontroller.callback()">Not isolated</button>',
            //NOT this                  
            //template: '<button ng-click="callback()">Not isolated</button>',
            controller: function ($attrs, $scope, $parse) {
                  //$scope.callback = $parse($attrs.callback)($scope);
            }
        }
    });
    

    由于指令没有自己的范围,模板可以直接访问使用ng-controller="MyCtrl as mycontroller" 实例化的控制器。


    如果你想重用指令怎么办?

    在这种情况下,将点击处理程序绑定到元素。

    .directive('helloWorld', function () {
        return {
            restrict: 'E',
            scope: false,
            template: '<button>Not isolated</button>',
            link: function (scope, elem, attrs) {
                 elem.on("click", function(e) {
                     scope.$eval(attrs.callback, {$event: e});
                 });
            }
        }
    });
    

    当点击指令的元素时,callback 属性定义的 Angular 表达式将使用暴露为 $event 的事件对象进行评估。

    有关$event 的更多信息,请参阅AngularJS Developer Guide -- $event

    【讨论】:

    • 如果要重用指令怎么办?
    猜你喜欢
    • 2015-05-14
    • 1970-01-01
    • 2014-07-30
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多