未调用隔离范围函数(多个日期选择器)

时间:2015-05-01 05:02:57

标签: javascript angularjs twitter-bootstrap

我试图在一个页面上使用多个ui.bootstrap.datepickers,为此我创建了一个带有隔离范围的指令来管理每个日期选择器的打开/关闭状态

请参阅Plunker(代码仅用于显示问题)

问题是没有调用toggle函数。但是当我改为scope: true时,它开始起作用。

任何人都可以解释这种行为吗?

1 个答案:

答案 0 :(得分:1)

JS

app.controller('MainCtrl', function($scope) {
$scope.toggle = function() {
  alert('you are in the wrong scope');
}
});

 app.directive('datepicker', function () {

        return {
            link: function(scope, element, attrs) {
            },
           controller: function ($scope) {
                $scope.opened = false;
                $scope.toggle = function ($event) {
                    alert('i am not being called');
                    //$event.preventDefault();
                    //$event.stopPropagation();
                    $scope.opened = !$scope.opened;
                };
            },
            scope: {},
            restrict: 'A'
        };
    })

HTML

  <body ng-controller="MainCtrl">
    <div datepicker>
      <input type="text" is-open="opened"/>
      <input type=button  ng-click="toggle($event)" value="show datepicker"/>
    </div>
    <input type=button  ng-click="toggle($event)" value="show datepicker"/>
  </body>

Plunker

在此示例中,您将看到有一个按钮作为datepicker指令的子项,而另一个不是。我还为MainCtrl的范围添加了一个切换功能。如果将指令的范围设置为true并单击datepicker内的按钮,它将触发属于datepicker的切换。如果单击另一个,它将触发MainCtrl上的切换。这是有效的,因为scope: true正在创建一个继承自MainCtrl范围的子范围。

如果将指令设置为scope: {},它将不会从MainCtrl继承,因此永远不会触发指令的切换功能。

  

scope:true - 该指令创建一个新的子范围   原型继承自父范围。如果不止一个   指令(在同一个DOM元素上)请求一个新范围,只有一个新范围   子范围已创建。既然我们有“正常”的原型继承,   这就像ng-include和ng-switch,所以要注意双向数据   绑定到父作用域基元和子作用域隐藏/阴影   父范围属性。

如果要使用隔离范围并调用函数,则需要将输入作为指令模板的一部分。现在你有了不同的范围,你可以在内部访问指令的功能。

JS

app.directive('datepicker', function () {

        return {
            link: function(scope, element, attrs) {
            },
           controller: function ($scope) {
                $scope.opened = false;
                $scope.toggle = function ($event) {
                    alert('i am not being called');
                    //$event.preventDefault();
                    //$event.stopPropagation();
                    $scope.opened = !$scope.opened;
                };
            },
            scope: {},
            restrict: 'A',
            template: '<input type="text" is-open="opened"/><input type=button  ng-click="toggle($event)" value="show datepicker"/>'
        };
    })

Plunker