2016-11-21 95 views
0

我正在嘗試構建自定義過濾器,這會將UTC中的datetime更改爲用戶時區的值。在AngularJs中構建自定義過濾器時出現錯誤

由於我是angularJs的新手,我不知道該怎麼辦以及在哪裏註冊過濾器。

我已經創建過濾器分隔的文件名爲clientTime.js:

export default function(startDateTimeString) { 

    let localTime = this.$rootscope.momentTimezone.utc(startDateTimeString).toDate(); 
    localTime = this.$rootscope.momentTimezone(localTime).format("YYYY-MM-DD HH:mm"); 

    return localTime; 
} 

作爲參數傳遞給我傳遞startDateTimeString的功能,這是在這個格式的日期 - 時間的字符串值:「YYYY- MM-DD HH:MM」

在我的HTML我已經使用過濾器是這樣的:

<tr st-select-row="row" st-select-mode="multiple" ng-repeat="row in dashCtrl.upcomingSessionsDisplay" ng-switch on="row.status" 
    ng-click="dashCtrl.handleClickOnUpcomingSessions(row)" title="{{dashCtrl.tooltip(row)}}"> 
    <td>{{row.locationName}}</td> 
    <td>{{row.startDateTimeString | clientTime}}</td> 
</tr> 

我有我在哪裏註冊的所有組件,如app.js:服務,攔截器等。所以我知道我應該在那裏註冊過濾器。

我有一個像所有其他部件進口過濾器:

import toastr from "toastr"; 
import _ from "underscore"; 
import momentTimezone from "moment-timezone"; 
import Components from "./components"; 
import Directives from "./shared/directives"; 
import Constants from "./shared/constants"; 
import Services from "./shared/services"; 
import Controllers from "./shared/controllers"; 
import AuthenticationInterceptor from "./shared/interceptors/AuthenticationInterceptor"; 
import ClientTime from "./shared/filters/clientTime"; 

而名爲「clientTime」註冊它:

angular 
    .module("examino.main", ["ui.router", "smart-table", "ui.bootstrap", "ui.tree", Directives, Components, Constants, Services, Controllers]) 

    .run(function($rootScope, $state, AuthenticationService) { 
     $rootScope._ = _; 
     $rootScope.momentTimezone = momentTimezone; 

     // register listener to watch route changes 
     $rootScope.$on("$stateChangeStart", function(event, toState, params) { 
      let goToStateName = "login"; 
      let isAccessTestSessionRoute = toState.name == "testEnv" || toState.name == "testEnv.dashboard" || toState.name == "sessionExpired"; 
      if(toState.name !== goToStateName && !AuthenticationService.isAuthenticated() && !isAccessTestSessionRoute) { 
       event.preventDefault(); 
       $state.go(goToStateName); 
      } 

      if(toState.redirectTo) { 
       event.preventDefault(); 
       $state.go(toState.redirectTo, params); 
      } 
     }); 
    }) 

    .config(function($urlRouterProvider, $locationProvider, $httpProvider) { 
     $locationProvider.html5Mode(true); 

     $urlRouterProvider.otherwise("/login"); 

     $httpProvider.interceptors.push("AuthenticationInterceptor"); 
    }) 
    .filter("clientTime", ClientTime) 

    .service("AuthenticationInterceptor", AuthenticationInterceptor); 

angular.bootstrap(document, ["examino.main"]); 

//set toastr options 
toastr.options = { 
    positionClass: "toast-top-full-width" 
}; 

我敢肯定,這將工作,但我得到這個錯誤:

> vendor.js:26519 Error: [$injector:unpr] Unknown provider: 
> startDateTimeStringProvider <- startDateTimeString <- clientTimeFilter 
> http://errors.angularjs.org/1.5.8/$injector/unpr?p0=startDateTimeStringProvider%20%3C-%20startDateTimeString%20%3C-%20clientTimeFilter 
>  at vendor.js:12667 
>  at vendor.js:17110 
>  at Object.getService [as get] (vendor.js:17263) 
>  at vendor.js:17115 
>  at getService (vendor.js:17263) 
>  at injectionArgs (vendor.js:17287) 
>  at Object.invoke (vendor.js:17309) 
>  at Object.enforcedReturnValue [as $get] (vendor.js:17156) 
>  at Object.invoke (vendor.js:17317) 
>  at vendor.js:17116 

現在我完全明白了什麼是問題,我猜測角度不要過濾器的rstand依賴關係。但我不確定這是什麼解決方案。 我從一個想法開始,即過濾器與服務或攔截器類似,它仍然是一個匿名函數,所以我認爲這是定義它的方式。有人可以分享他們的經驗,創建過濾器和依賴性問題的可能解決方案嗎?

回答

1

問題在於你如何定義你的過濾器。 'angular.filter'期望過濾器工廠功能,根據文檔(編寫你自己的過濾器非常簡單:只需在模塊中註冊一個新的過濾器工廠功能 - https://docs.angularjs.org/guide/filter)。

所以,你clientTime.js應

export default function() { 
 
    return function(startDateTimeString) { 
 

 
    let localTime = this.$rootscope.momentTimezone.utc(startDateTimeString).toDate(); 
 
    localTime = this.$rootscope.momentTimezone(localTime).format("YYYY-MM-DD HH:mm"); 
 

 
    return localTime; 
 
    } 
 
}

正如你所看到的,現在模塊出口,返回你的過濾功能的函數。現在它應該工作。

+0

是的,你是對的。現在我還有其他問題,$ rootcope無法識別,我期待着發生這種情況。我將不得不找到一種方法來通過$ rootcope來過濾,但這是一個完整的其他問題。感謝您的幫助。 @ igor.araujo –

+0

您應該在過濾器工廠函數中注入$ rootScope:export default function($ rootScope){...} 不要忘記從過濾器代碼 –

+0

中刪除'this'變量,這是我第一次已經做到了,但它不起作用。當我刪除'這個'它說$ rootcope沒有定義。我是否需要做這樣的事情?$ rootscope = $ rootscope?但我不會幫助的事情... @ ivan.araujo –

0

我沒用過那麼多,但我所記得的,你需要創建一個過濾器組件,像這樣

angular.module('yourModule') 
    .filter('clientTime', function() { 
     // Your code 
    }); 

過濾器和我沒有看到它在您的文章。也許這就是爲什麼它不起作用?

+0

你好,謝謝你的回覆。我也看到了這種方式,但我想這是一種在app.js中創建過濾器的方法,我想將它製作在一個單獨的文件中,這就是爲什麼我缺少該代碼。 @trichetriche –

+0

就像你說的那樣,你不需要把所有東西放在「app.js」中。我的項目中有30到40個JS文件,都包含單個組件(控制器,服務,工廠,常量,配置等)。您只需創建一個單獨的文件,將JS標籤放入索引中。 html文件,並將你的過濾器放在分開的文件中。但是你需要按照規定去做。 – trichetriche

相關問題