2015-05-15 42 views
5

我有一個表單,我需要用戶輸入一個持續時間,在資源中這被保存爲分鐘(或毫秒,容易改變)。我需要指令取秒/毫秒值,然後爲分鐘創建3個單獨的輸入,秒數爲&毫秒。在AngularJS指令中創建持續時間輸入(mm:ss:ms)

用戶然後可以修改每個組件,然後指令將使用3個組件的秒/毫秒值更新模型。

我似乎能夠取模型值,創建3個輸入並使用moment.js創建時間的單獨組件。

指令

angular.module('myExampleApp') 
    .directive('lapTimeInput', function() { 
    var tpl = '<div class="lap_time_input"> \ 
       <input ng-model="lap_time.minutes" type="number" class="minutes" placeholder="00" min="0" max="15" step="1"> \ 
      <span class="lap-time-sep">:</span> \ 
      <input ng-model="lap_time.seconds" type="number" class="seconds" placeholder="00" min="0" max="59" step="1"> \ 
      <span class="lap-time-sep">.</span> \ 
      <input ng-model="lap_time.milliseconds" type="number" class="milliseconds" placeholder="000" min="0" max="999" step="1"> \ 
      </div>'; 

    return { 
     restrict: 'A', 
     template: tpl, 
     replace: true, 
     require: 'ngModel', 
     scope: { 
     }, 
     link: function (scope, element, attrs, ngModel) { 

      if (!ngModel) return; 

      scope.$watch(function() { 
       return ngModel.$modelValue; 
      }, function(newValue) { 
       // Using moment.js to extract min, sec & ms parts 
       var duration = moment.duration(newValue, 'seconds'); 
       scope.lap_time = { 
        minutes: duration.minutes(), 
        seconds: duration.seconds(), 
        milliseconds: duration.milliseconds() 
       } 
      }); 
     } 
    }; 
    }); 

控制器

$scope.lap = Lap.get({ id: 1 }); // $resource contains .lap_time property 
// OR 
$scope.lap = { 
    lap_time: 90.999 
} 

HTML

<input type="text" lap-time-input ng-model="lap.lap_time" /> 

這Plunker將希望b E中的更清楚一點

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

現在,我甚至不知道我已經走了下來用在ngModel $手錶正確的道路,我猜不會。據我所知,我所需要的指令做3兩件事:

  • 與分,秒3個獨立的輸入和毫秒
  • 使用創建的輸入顯示在創建的輸入模型來讓用戶更換濾芯
  • 當用戶改變任何的3個輸入,它更新模型值轉動3個單獨的值回秒/毫秒

即使只是在正確的方向輕推將是一個很大的幫助

回答

1

這是我設法提出的。不是確切的答案,但應該幫助你。

模板

更新模板和在所述圈時間經過作爲屬性經由指令範圍來獲得(參見指令部)

<div lap-time-input="lap.lap_time"></div> 

控制器

angular.module('myExampleApp') 
    .controller('myExampleCtrl', function ($scope) { 

     // This would usually be a $resouce return via a serice 
     $scope.lap = { 
      lap_time: 90.999 
     }; 

     // watch value of lap time change here when you update minute/second/millisecond 
     $scope.$watch('lap.lap_time', function (newLapTime) { 
      console.log('newLapTime', newLapTime); 
     }); 
}); 

指令

將第二個/毫秒輸入字段添加到模板。你可能不需要它,但是爲了視覺/調試的原因,我把它放在那裏。

angular.module('myExampleApp') 
    .directive('lapTimeInput', function() { 
    var tpl = '<div class="lap_time_input"> \ 
       <input ng-model="lapTimeInput" type="number" placeholder="00.00"> \ 
       <input ng-model="lap_time.minutes" type="number" class="minutes" placeholder="00" min="0" max="15" step="1"> \ 
      <span class="lap-time-sep">:</span> \ 
      <input ng-model="lap_time.seconds" type="number" class="seconds" placeholder="00" min="0" max="59" step="1"> \ 
      <span class="lap-time-sep">.</span> \ 
      <input ng-model="lap_time.milliseconds" type="number" class="milliseconds" placeholder="000" min="0" max="999" step="1"> \ 
      </div>'; 

    return { 
     restrict: 'A', 
     template: tpl, 
     replace: true, 
     scope: { 
      lapTimeInput: '=' 
     }, 
     link: function (scope) { 

      // watch for changes in lapTimeInput and update the lap_time model/object 
      scope.$watch('lapTimeInput', function (newValue) { 
       var duration = moment.duration(newValue, 'seconds'); 
       scope.lap_time = { 
        minutes: duration.minutes(), 
        seconds: duration.seconds(), 
        milliseconds: duration.milliseconds() 
       } 
      }); 

      // watch for changes in the lap_time model/object 
      scope.$watchCollection('lap_time', function (newTime, oldTime) { 
       console.log(newTime); 
       // convert back to lap time with momentjs here 
       scope.lapTimeInput = moment.duration(newTime, 'seconds').asSeconds(); 

      }); 
     } 
    }; 
}); 

JSFIDDLE

1

好吧,我已經成功與ngModel做到不添加任何代碼到控制器,因爲我需要在多個位置使用此指令。我也能夠做驗證標記。

angular.module('exampleApp') 
.directive('lapTimeInput', function() { 
var tpl = '<div class="lap-time-input"> \ 
     <div class="input-group"> \ 
      <span class="input-group-addon"><label for="laps">Lap Time</label></span> \ 
      <input ng-model="lap_time.minutes" type="number" class="form-control minutes" name="minutes" placeholder="00" min="0" max="15" step="1"> \ 
     </div> \ 
     <span class="form-control lap-time-sep">:</span> \ 
     <input ng-model="lap_time.seconds" type="number" class="form-control seconds" placeholder="00" min="0" max="59" step="1"> \ 
     <span class="form-control lap-time-sep">.</span> \ 
     <input ng-model="lap_time.milliseconds" type="number" class="form-control milliseconds" placeholder="000" min="0" max="999" step="1"> \ 
     </div>'; 

return { 
    restrict: 'A', 
      template: tpl, 
      replace: true, 
      require: 'ngModel', 
      link: function (scope, element, attrs, ngModel) { 

       if (!ngModel) return; 

       ngModel.$formatters.unshift(function(modelValue) { 
        if(!modelValue) return; 

        var duration = moment.duration(parseInt(modelValue)); 
        return { 
         minutes: duration.minutes(), 
         seconds: duration.seconds(), 
         milliseconds: duration.milliseconds() 
        }; 
       }); 

       ngModel.$render = function() { 
        scope.lap_time = ngModel.$viewValue 
       }; 

       ngModel.$parsers.unshift(function(modelVal) {   
        var duration = moment.duration(scope.lap_time); 

        return duration.asMilliseconds(); 
       }); 

       ngModel.$validators.check = function(modelValue, viewValue) {   
        if(viewValue) { 
         if(viewValue.minutes === undefined || viewValue.minutes > 15) { 
          return false; 
         } 
         if(viewValue.seconds === undefined || viewValue.seconds > 59) { 
          return false; 
         } 
         if(viewValue.milliseconds === undefined || viewValue.milliseconds > 999) { 
          return false; 
         } 
        } 
        return true; 
       }; 

       scope.$watchCollection('lap_time', function(newVal) { 
        ngModel.$setViewValue(newVal); 
       }); 

    } 
    }; 
}); 

如果我在這裏有問題,歡迎反饋。