2016-03-03 35 views
1

Angular UI Bootstrap在1.13.0之後的某個版本中改變了datepicker期望的方式,即ng-model。給它一個ISO日期字符串是好的,現在它想要一個Date對象。AngularJS:創建用於將字符串轉換爲動態日期的指令

我消費從我的API ISO日期字符串了,所以我必須

  • 它們轉換成Date對象給它的日期選擇器之前和
  • 將它們存儲在其轉換回ISO日期字符串。

在過去,我用這樣的指令:

function DateObjectDirective() { 
    const directive = { 
    restrict: "A", 
    require: ["ngModel"], 
    link(scope, element, attributes, controllers) { 
     const ngModel = controllers[0]; 

     ngModel.$formatters.unshift(value => { 
      let output = null; 

      if(value) { 
      output = moment(value).toDate(); 
      } 

      return output; 
     }); 

     ngModel.$parsers.unshift(value => { 
      let output = null; 

      if(value) { 
      output = moment(value).format(); 
      } 

      return output; 
     }); 
    }, 
    }; 

    return directive; 
} 

此不再工作,雖然,如下面的錯誤報告:

this.activeDate.getFullYear不是功能

我的猜測是,日期選擇器仍然使用字符串作爲參考。在將數據提交給日期選擇器之前,是否有其他方式可以轉換?

回答

1

我發現我發佈的指令確實仍然有效。唯一的問題是AngularJS評估指令的訂單號碼爲

例如:

<input ng-model="someDateString" uib-datepicker-popup="yyyy-MM-dd" woo-date-object> 

在我的情況,woo-date-object總是uib-datepicker-popup之前評估。結果是datepicker總是在ngModel.$formatters的頂部推送自己的格式化程序,從而消除了我插手的可能性。

解決方案是給自己的指令更高的優先級。 UI的日期選擇器沒有一組,所以任何大於0(這是默認的)工作原理:

{ 
    restrict: "A", 
    require: "ngModel", 
    priority: 9999, 
    link(scope, element, attributes, ngModel) { 
    ngModel.$formatters.push(value => { 
     let output = new Date(); 
     if(value) { output = moment(value).toDate(); } 
     return output; 
    }); 

    ngModel.$parsers.push(value => { 
     let output = null; 
     if(value) { output = moment(value).format(); } 
     return output; 
    }); 
    }, 
} 
+1

我認爲,如果你命名你的指令uibDatepickerPopup你甚至不會需要定義指令(宇日期 - 對象)在元素上。 –

+1

@RobJ'uibDatepickerPopup'已經由AngularUI Bootstrap定義。另外我更喜歡能夠在需要時使用它,而不是所有時間。 – stschindler

+3

Angular允許您通過使用相同的名稱併爲執行順序設置優先級來擴展指令。 –