刚开始旁边的同事一直说是在线编译导致速度慢,后来看到提示有https://github.com/shootaroo/jit-grunt#static-mappings
进去看了说明再检查工程里面是有配置的, 所以不是这个问题.
require('jit-grunt')(grunt);
然而怎么改本地数据都没用, 一定是从网上在线请求了欧洲版的数据.
查看Network, 里面vendor.js的请求最多, sources搜language打断点停在这:
function $translate($STORAGE_KEY, $windowProvider, $translateSanitizationProvider,
pascalprechtTranslateOverrider) { "use strict"; var $preferredLanguage, $languageKeyAliases, $fallbackLanguage,
$fallbackWasString, $uses, $nextLang, $storageFactory, $storagePrefix,
$missingTranslationHandlerFactory, $interpolationFactory, $loaderFactory,
$loaderOptions, $notFoundIndicatorLeft, $notFoundIndicatorRight, loaderCache,
$translationTable = {}, $availableLanguageKeys = [], $storageKey = $STORAGE_KEY,
$interpolatorFactories = [], $cloakClassName = "translate-cloak",
$postCompilingEnabled = !1, $forceAsyncReloadEnabled = !1,
$nestedObjectDelimeter = ".", $isReady = !1, directivePriority = 0,
statefulFilter = !0, uniformLanguageTagResolver = "default", languageTagResolver = {
奶奶的调了这么个接口...
具体到页面html是index.html,login.html,language-switcher.html
在index.html中查看网页源代码最终显示出来的静态代码和app文件夹下html/index.html是一致的:
<section class="main-content"> <div data-global-messages></div> <div data-ng-view=""> <div data-ng-controller="PopupController" ng-init="openModal()"> <script type="text/ng-template"> <div data-popup></div> </script> </div> </div> </section>
东西都在ng-template内部, 登录部分是auth-box login-box:
<div class="auth-box login-box ng-scope"><h3 class="ng-binding">Login</h3>
这部分html
<div class="auth-box login-box"> <h3>{{ 'login.title' | translate}}</h3> <form name="loginForm" novalidate data-login-form="loginCtrl.loginPromise"> <div class="validation-block global-errors" data-ng-messages="loginForm.$api.$error" data-ng-if="loginForm.$submitted"> <div data-ng-messages-include="html/validation/form-messages.html"></div> </div> <div class="form-group"> <label for="customerCode">{{ 'login.customerCode' | translate }}</label> <div class="error-text"> <input data-ng-model="user.customerCode" type="text" name="customerCode" required class="form-control" id="customerCode" data-ng-class="(loginForm.customerCode.$touched || loginForm.$submitted) ? 'validated' : ''"> <div class="validation-block field-errors" data-ng-messages="loginForm.customerCode.$error" data-ng-if="loginForm.customerCode.$touched || loginForm.$submitted"> <div data-ng-messages-include="html/validation/messages.html"></div> </div> </div> </div> <div class="form-group"> <label for="login-password">{{ 'login.password' | translate }}</label> <div class="error-text"> <input data-ng-model="user.password" type="password" name="password" required class="form-control" id="login-password" data-ng-class="(loginForm.password.$touched || loginForm.$submitted) ? 'validated' : ''"> <div class="validation-block field-errors" data-ng-messages="loginForm.password.$error" data-ng-if="loginForm.password.$touched || loginForm.$submitted"> <div data-ng-messages-include="html/validation/messages.html"></div> </div> </div> </div> <div class="form-group"> <label>{{'editUser.language' | translate }} <em>*</em></label> <div class="error-text"> <ui-select showErrors data-api-validate id="language" name="language" data-ng-model="user.language" required theme="bootstrap" ng-disabled="disabled" style="min- 300px;"> <ui-select-match ><img ng-src="{{ $select.selected.url }}"/> {{$select.selected.key}}</ui-select-match> <ui-select-choices repeat="lang.value as lang in languages"> <img ng-src="{{ lang.url }}" /> <div ng-bind-html="lang.key" style="display: inline"></div> </ui-select-choices> </ui-select> <div class="validation-block field-errors" data-ng-messages="loginForm.language.$error" data-ng-if="loginForm.language.$touched || loginForm.$submitted"> <div data-ng-messages-include="html/validation/messages.html"> </div> </div> </div> </div> </form> </div>
最终会变成
<div class="auth-box login-box ng-scope"><h3 class="ng-binding">Login</h3> <form name="loginForm" novalidate="" data-login-form="loginCtrl.loginPromise" class="ng-pristine ng-invalid ng-invalid-required ng-valid-api-validate"> <!-- ngIf: loginForm.$submitted --> <div class="form-group"><label for="customerCode" class="ng-binding">Customer Code</label> <div class="error-text"><input data-ng-model="user.customerCode" type="text" name="customerCode" required="" class="form-control ng-pristine ng-untouched ng-invalid ng-invalid-required" id="customerCode" data-ng-class="(loginForm.customerCode.$touched || loginForm.$submitted) ? 'validated' : ''"> <!-- ngIf: loginForm.customerCode.$touched || loginForm.$submitted --> </div> </div> <div class="form-group"><label for="login-password" class="ng-binding">Password</label> <div class="error-text"><input data-ng-model="user.password" type="password" name="password" required="" class="form-control ng-pristine ng-untouched ng-invalid ng-invalid-required" id="login-password" data-ng-class="(loginForm.password.$touched || loginForm.$submitted) ? 'validated' : ''"> <!-- ngIf: loginForm.password.$touched || loginForm.$submitted --> </div> </div> <div class="form-group"><label class="ng-binding">Language <em>*</em></label> <div class="error-text"> <div class="ui-select-container ui-select-bootstrap dropdown ng-invalid ng-invalid-required ng-valid-api-validate open" ng-class="{open: $select.open}" showerrors="" data-api-validate="" id="language" name="language" data-ng-model="user.language" required="required" theme="bootstrap" ng-disabled="disabled" style="min- 300px;"><div class="ui-select-match ng-hide" ng-hide="$select.open" ng-disabled="$select.disabled" ng-class="{'btn-default-focus':$select.focus}" style=""><span tabindex="-1" class="btn btn-default form-control ui-select-toggle" aria-label="Select box activate" ng-disabled="$select.disabled" ng-click="$select.activate()" style="outline: 0;"><span ng-show="$select.isEmpty()" class="ui-select-placeholder text-muted ng-binding"></span> <span ng-hide="$select.isEmpty()" class="ui-select-match-text pull-left ng-hide" ng-class="{'ui-select-allow-clear': $select.allowClear && !$select.isEmpty()}" ng-transclude=""><img class="ng-scope"><span class="ng-binding ng-scope"> </span></span> <i class="caret pull-right" ng-click="$select.toggle($event)"></i> <a ng-show="$select.allowClear && !$select.isEmpty()" aria-label="Select box clear" style="margin-right: 10px" ng-click="$select.clear($event)" class="btn btn-xs btn-link pull-right ng-hide"><i class="glyphicon glyphicon-remove" aria-hidden="true"></i></a></span></div><input type="text" autocomplete="false" tabindex="-1" aria-expanded="true" aria-label="Select box" aria-owns="ui-select-choices-0" aria-activedescendant="ui-select-choices-row-0-0" class="form-control ui-select-search ng-pristine ng-valid ng-touched" placeholder="" ng-model="$select.search" ng-show="$select.searchEnabled && $select.open" style=""><ul class="ui-select-choices ui-select-choices-content ui-select-dropdown dropdown-menu ng-scope" role="listbox" ng-show="$select.items.length > 0" repeat="lang.value as lang in languages" style="opacity: 1;"><li class="ui-select-choices-group" id="ui-select-choices-0"><div class="divider ng-hide" ng-show="$select.isGrouped && $index > 0"></div><div ng-show="$select.isGrouped" class="ui-select-choices-group-label dropdown-header ng-binding ng-hide" ng-bind="$group.name"></div><!-- ngRepeat: lang in $select.items --><!-- ngIf: $select.open --><div id="ui-select-choices-row-0-0" class="ui-select-choices-row ng-scope active" ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" role="option" ng-repeat="lang in $select.items" ng-if="$select.open" ng-mouseenter="$select.setActiveItem(lang)" ng-click="$select.select(lang,false,$event)" style=""><a href="" class="ui-select-choices-row-inner" uis-transclude-append=""><img ng-src="images/gif/en.gif" class="ng-scope" src="images/gif/en.gif"> <div ng-bind-html="lang.key" style="display: inline" class="ng-binding ng-scope">English</div> </a></div><!-- end ngIf: $select.open --><!-- end ngRepeat: lang in $select.items --><!-- ngIf: $select.open --><div id="ui-select-choices-row-0-1" class="ui-select-choices-row ng-scope" ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" role="option" ng-repeat="lang in $select.items" ng-if="$select.open" ng-mouseenter="$select.setActiveItem(lang)" ng-click="$select.select(lang,false,$event)"><a href="" class="ui-select-choices-row-inner" uis-transclude-append=""><img ng-src="images/gif/zh.gif" class="ng-scope" src="images/gif/zh.gif"> <div ng-bind-html="lang.key" style="display: inline" class="ng-binding ng-scope">简体中文</div> </a></div><!-- end ngIf: $select.open --><!-- end ngRepeat: lang in $select.items --><!-- ngIf: $select.open --><div id="ui-select-choices-row-0-2" class="ui-select-choices-row ng-scope" ng-class="{active: $select.isActive(this), disabled: $select.isDisabled(this)}" role="option" ng-repeat="lang in $select.items" ng-if="$select.open" ng-mouseenter="$select.setActiveItem(lang)" ng-click="$select.select(lang,false,$event)"><a href="" class="ui-select-choices-row-inner" uis-transclude-append=""><img ng-src="images/gif/kr.gif" class="ng-scope" src="images/gif/kr.gif"> <div ng-bind-html="lang.key" style="display: inline" class="ng-binding ng-scope">한글</div> </a></div><!-- end ngIf: $select.open --><!-- end ngRepeat: lang in $select.items --></li></ul><ui-select-single></ui-select-single><input ng-disabled="$select.disabled" class="ui-select-focusser ui-select-offscreen ng-scope" type="text" id="focusser-0" aria-label="Select box focus" aria-haspopup="true" role="button" disabled=""></div> <!-- ngIf: loginForm.language.$touched || loginForm.$submitted --> </div> </div> </form> </div>
可是看出directive是showErrors
(function(){ var showErrors = function(){ return { restrict: 'A', require: '^form', link: function (scope, el, attrs, formCtrl) { // find the text box element, which has the 'name' attribute var inputEl = el[0].querySelector("[name]"); // convert the native text box element to an angular element var inputNgEl = angular.element(inputEl); // get the name on the text box var inputName = inputNgEl.attr('name'); // only apply the has-error class after the user leaves the text box var blurred = false; inputNgEl.bind('blur', function() { blurred = true; el.toggleClass('has-error', formCtrl[inputName].$invalid); }); scope.$watch(function() { return formCtrl[inputName].$invalid }, function(invalid) { // we only want to toggle the has-error class after the blur // event or if the control becomes valid if (!blurred && invalid) { return } el.toggleClass('has-error', invalid); }); scope.$on('show-errors-check-validity', function() { el.toggleClass('has-error', formCtrl[inputName].$invalid); }); scope.$on('show-errors-reset', function() { $timeout(function() { el.removeClass('has-error'); }, 0, false); }); } } }; angular.module('api') .directive('showErrors',showErrors)})();
插件ui-select用法 : http://v7sky.iteye.com/blog/2304175
应用的启动从app.js开始, 也就是后来被打包成scripts.js的部分:
(function () { 'use strict'; var appConfig = function ($routeProvider, jwtInterceptorProvider,
$httpProvider, $locationProvider,$provide) { $routeProvider.otherwise('/404'); $provide.decorator('$locale', ["$delegate", function ($delegate) { var value = $delegate.DATETIME_FORMATS; ...... return $delegate; }]);
$httpProvider.interceptors.push('jwtInterceptor');
$httpProvider.interceptors.push('TokenInterceptor');
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
$locationProvider.html5Mode(true);
};
appConfig.$inject = ['$routeProvider', 'jwtInterceptorProvider', '$httpProvider', '$locationProvider','$provide'];
var appRun = function ($rootScope,$window, $location, jwtHelper,$translate, AuthService,
$sessionStorage,deviceDetector) { $rootScope.isMobile="is_mobile"; $rootScope.screenWidth=$window.innerWidth; if ((deviceDetector.os==="android"||deviceDetector.os==="ios" ||deviceDetector.os==="windows-phone"||
deviceDetector.device==="blackberry")&& $rootScope.screenWidth<768) $rootScope.isMobile=true; else $rootScope.isMobile=false; // Store user data in $rootScope.account if user is logged in if ($sessionStorage.jwt && !jwtHelper.isTokenExpired($sessionStorage.jwt)) { var jwt = $sessionStorage.jwt; $rootScope.account = jwt && jwtHelper.decodeToken(jwt); } $rootScope.$on('$routeChangeStart', function... ...);
appRun.$inject = ['$rootScope', '$window','$location', 'jwtHelper','$translate', 'AuthService', '$sessionStorage','deviceDetector'];
angular.module('appName',['moduleName',... ...]) .config(appConfig) .run(appRun); })();
就像以前避免走车机接口, 这次要避免http接口了...
在 appjsangular ranslate ranslate.service.js:专门写了一个service:
(function () { 'use strict'; var TranslateService = function($translate) { var service = this; service.changeLanguage = function (languageKey) { $translate.use(languageKey); }; service.setDefaultLanguage = function () { $translate.use($translate.preferredLanguage()); }; }; TranslateService.$inject = ['$translate']; angular .module('translate') .service('TranslateService', TranslateService); })();
此处的angular文件夹都是自定义的service