2016-03-05 161 views
3

我正在建造某种日期选择器,实际上是2日期选择器。 一个用于开始日期,另一个用于结束日期。每个datepicker元素生成一个包含2个输入标签()的模板。我想从输入的值属性传递数据到控制器。 我试图在内部作用域中定义两个数据绑定(dateOne和dateTwo)的字段,但显然没有效果,并且没有真正的数据在两个字段之间传递。 我的另一种方法是使用ng-model,但我对这个功能的使用很少,我不知道这些规则。 这是我的代码如何将数据从指令模板传递到控制器?

angular.module('directives', []) 
    .directive('datepicker', ['$timeout',function ($timeout) { 
     // Runs during compile 
     return { 
      scope: { 
       id: '@', 
       "class": '@', 
       dateOne: '=', 
       dateTwo: '=' 
      }, 
       restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment 
       template: '<div id="{{id}}" class="{{class}}">'+ 
         '<div class="date-wrapper">'+ 
          '<label for="datepicker-start">From:</label>'+ 
          '<div class="fieldWrapper">'+ 
           '<input id="datepicker-start" type="date" placeholder="Select date" value={{dateOne}} />'+ 
           '<a class="calendar"></a>'+ 
          '</div>'+ 
         '</div>'+ 
         '<div class="date-wrapper">' + 
          '<label for="datepicker-end">To:</label>' + 
          '<div class="fieldWrapper">' + 
           '<input id="datepicker-end" type="date" placeholder="Select date" value={{dateTwo}}/>' + 
           '<a class="calendar"></a>' + 
          '</div>' + 
         '</div>'+ 
         '</div>' 
         , 
       replace: true, 
      link: function($scope, iElm, iAttrs, controller) { 
       console.log('directive link function'); 
       console.log('directive iAttrs', iAttrs); 
       $(".date-wrapper").each(function (index) { 
        console.log('directive index', index); 
        $input = $(this).find('input'); 
        $btn = $(this).find('.calendar'); 

        console.log('input', $input[0]); 
        console.log('btn', $btn[0]); 

        $input.attr('type', 'text'); 
        var pickerStart = new Pikaday({ 
         field: $input[0], 
         trigger: $btn[0], 
         container: $(this)[0], 
         format: 'DD/MM/YYYY', 
         firstDay: 1 
        }); 
        $btn.show(); 
       }); 

      } 
     }; 
}]); 

------------------------更新后的代码------------ -----------------------

angular.module('directives', []) 
    .directive('datepicker', ['$timeout',function ($timeout) { 
     // Runs during compile 
     return { 
      scope: { 
       id: '@', 
       "class": '@', 
       dateOne: '=', 
       dateTwo: '=' 
      }, 
       restrict: 'E', // E = Element, A = Attribute, C = Class, M = Comment 
       template: '<div id="{{id}}" class="{{class}}">'+ 
         '<div class="date-wrapper">'+ 
          '<label for="datepicker-start">From:</label>'+ 
          '<div class="fieldWrapper">'+ 
           '<input id="datepicker-start" type="date" placeholder="Select date" ng-model=dateOne />' + 
           '<a class="calendar"></a>'+ 
          '</div>'+ 
         '</div>'+ 
         '<div class="date-wrapper">' + 
          '<label for="datepicker-end">To:</label>' + 
          '<div class="fieldWrapper">' + 
           '<input id="datepicker-end" type="date" placeholder="Select date" ng-model=dateTwo />' + 
           '<a class="calendar"></a>' + 
          '</div>' + 
         '</div>'+ 
         '</div>' 
         , 
       replace: true, 
      link: function($scope, iElm, iAttrs, controller) { 
       console.log('directive iAttrs', iAttrs); 
       $(".date-wrapper").each(function (index) { 
        console.log('directive index', index); 
        $input = $(this).find('input'); 
        $btn = $(this).find('.calendar'); 

        console.log('input', $input[0]); 
        console.log('btn', $btn[0]); 

        $input.attr('type', 'text'); 
        var pickerStart = new Pikaday({ 
         field: $input[0], 
         trigger: $btn[0], 
         container: $(this)[0], 
         format: 'DD/MM/YYYY', 
         firstDay: 1 
        }); 
        $btn.show(); 
       }); 

       $scope.$watch(iAttrs.dateOne, function (newValue, oldValue) { 
        console.log('newValue', newValue); 
        console.log('oldValue', oldValue); 
       }, true); 

      } 
     }; 

回答

0
  1. 与NG-模型= dateOne并用dateTwo相同的模板替换值。

  2. 我建议为这个指令使用专用控制器,而不是在链接函数内部执行逻辑。

app.directive( 'someDirective',函数(){ 返回{ 限制: 'A', 控制器: 'SomeController', controllerAs: 'CTRL', 模板:“{{CTRL .foo}}' }; });

在这里阅读更多http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html

+0

我需要写ng-model = {{dateOne}}还是只是dateOne? – Brk

+0

如何查看这些值,我仍然无法跟踪任何更改。如果没有{{}},则为 – Brk

+0

。值通过双向绑定进行更新。请显示更新的代码 –

2

其实你几乎没有,我已经做了非常类似的东西你所描述的,在这里是我的方法来解决它(我使用的UI,引导日期选择器在我的情况)。

将数据从指令发送到控制器的方式是使用回调函数,而不是简单的手表。如果您会使用=,则必须在控制器(和指令)中设置手表才能观察值的变化,这是整体和额外代码的糟糕做法。

所以基本上你需要做的是

  1. 在你的指令定义对象使用&标志,像这样

    scope: { 
        onSelect: "&" // onSelect is our callback function in the ctrl 
    } 
    
  2. 绑定一个回调方法/函数,那么您提供一个回调属性一个绑定到控制器$ scope的函数,但是你传递了一个函数引用(不像函数调用那样像ng改变的那样)。像这样

    <my-directive on-selected="onSelected"></my-directive>

  3. 然后定义什么onSelected应该做的,可以说我想要打印选定日期

    // inside controller 
    $scope.onSelected = function(time) { 
        console.log("Time selected: ", time); 
    } 
    

请注意,我们打发时间参数从指令像这样的控制器,scope.onSelect()实际上是一个curried函数,这意味着它将返回一个曾经调用的函数(也就是说,如果您提供了函数,则可以使用angular.isFunction对其进行测试),所以你应该调用curried函数并提供你的参数,scope.onSelect()(time)

scope.selectDate = function(time) { 
    if (angular.isFunction(scope.onSelect())) { 
     // we use isFunction to test if the callback function actually 
     // points to a valid function object 
     scope.onSelect()(time); // we pass out new selected date time 
     } 
    } 

这是一个plunk显示我的意思。

相关问题