带有回调的1页上的多个自定义指令

时间:2014-08-19 16:14:06

标签: javascript angularjs angularjs-directive angularjs-scope

我创建了一个自定义指令(在SO的帮助下)。它是一个完整的日期选择器,它使用ngModel设置用户选择日期的日期。同时它调用一个回调函数,该函数在指令添加到页面时设置。问题是,如果我在页面上放置2个日期选择器,那么它总是尝试从第二个调用回调。

这是HTML ...

<fp-date-picker ng-model="dateOne" on-select="dateSelectedOne()"></fp-date-picker>

<fp-date-picker ng-model="dateTwo" on-select="dateSelectedTwo()"></fp-date-picker>

这是我的指示,其中大部分都是为了简洁而删除的

angular.module('directives').directive('fpDatePicker', ['$parse', function ($parse) {

    return {

        restrict: 'EA',
        require: 'ngModel',
        templateUrl: '/templates/fpDatePicker.tpl.html',

        link: function($scope, $element, $attrs, ngModel){

            // A callback executed when a date is selected
            var onSelectCallback = $parse($attrs.onSelect);


            // Set current month
            $scope.selectedDate = moment();



            // Set date when one is clicked
            $scope.selectDate = function(day){

                var selectedDay = day.number;
                var selectedMonth = $scope.currentMonth.format('MM');
                var selectedYear = $scope.currentMonth.format('YYYY');

                $scope.selectedDate = moment(selectedYear + '-' + selectedMonth + '-' + selectedDay, 'YYYY-MM-DD');

                // Update the model
                ngModel.$setViewValue($scope.selectedDate);


                // Call the on-select callback
                onSelectCallback($scope);

            };


        }


    };

}]);

以防万一需要,这是我的指令模板......

<div class="fpDatePicker-controls">
    <a href="#" ng-click="previousMonth()">&lt;</a>
    <a href="#" ng-click="nextMonth()">&gt;</a>
</div>
<div class="fpDatePicker-month">
    <a class="fpDatePicker-day" 
        ng-repeat="day in currentMonth.days" 
        ng-click="selectDate(day)"
    >
        {{day.number}}
    </a>
</div>

我认为它始终使用来自页面上指令的最后一个实例的回调的问题可能与链接函数中的变量对于该指令的所有实例的全局变量有关,或者$ attrs不是该指令的当前实例的attrs,但我使用console.log()来显示$ attrs,并且每种情况都不同。

我也想知道它是否与使作用域隔离有关,但是虽然回调函数位于作用域上,但属性中的表达式不是作用域的一部分,它是传入的属性。

非常困惑,任何帮助都会非常感激。

更新:创建了一个Plunkr

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

1 个答案:

答案 0 :(得分:3)

您的问题来自于您的指令不依赖于隔离范围的事实。因此两个指令实例共享相同的范围。创建第二个指令时,它会覆盖所有范围变量。

您可以在doc:https://docs.angularjs.org/guide/directive中了解有关隔离范围的更多信息。

这是一个显示如何使用隔离范围的plunkr: http://plnkr.co/edit/U64sbukqfFW0NQmvIC1a

我已更新您的标记,使其与控制器兼容,如语法:

<body ng-controller="MainCtrl as main">
    {{main.dateOne}}
    <fp-date-picker ng-model="main.dateOne" on-select="main.dateSelectedOne()"></fp-date-picker>

    <br />
    <br />
    <br />

    {{main.dateTwo}}
    <fp-date-picker ng-model="main.dateTwo" on-select="main.dateSelectedTwo()"></fp-date-picker>

</body>

指令定义的主要变化是使用指令定义对象中的scope属性来建立一个隔离的范围:

.directive('fpDatePicker', function() {

    return {
      scope: {
        select: '&onSelect'
      },

      restrict: 'EA',
      require: 'ngModel',
      templateUrl: 'datepicker.html',

      link: function($scope, $element, $attrs, ngModel) { ... }
     };
  })

请注意您的代码仍然存在日期选择问题。点击一天将选择前一天的日期。我没有解决这个问题。如果你需要帮助,请告诉我

相关问题