我有一组标签作为模块标签,它们必须是彼此的兄弟姐妹和主视图容器的第一个子节点。
如果用户通过身份验证,我想互相调用前两个。
我可以验证范围内是否有isAuthenticated
,但我所拥有的条件没有得到遵守。此外,出于性能原因,我还想避免调用整个隐藏模块。
我做错了什么以及包含一组模块标签的最佳条件是什么?
<sol-tabs id="main-vifirstew" data-loggedin="{{isAuthenticated}}" selected="{{defaultTab}}">
<dashboard-pane
ng-if="isAuthenticated == true"
<!--ng-show="isAuthenticated == true"
ng-hide="isAuthenticated == false" i've tried all these directives and none work -->
tab-icon="ambiance" ></dashboard-pane>
<user-login
ng-if="isAuthenticated == false"
<!--ng-hide="isAuthenticated == true"
ng-show="isAuthenticated == false"-->
tab-icon="login" ></user-login>
<third-pane tab-icon="search"></third-pane>
<fourth-pane tab-icon="list-ol"></fourth-pane>
</sol-tabs>
用户登录模块:
import 'angular';
var app = angular.module('user-login', ['sol-backend', 'services'])
.constant('AUTH_EVENTS', {
loginSuccess: 'auth-login-success',
loginFailed: 'auth-login-failed',
logoutSuccess: 'auth-logout-success',
sessionTimeout: 'auth-session-timeout',
notAuthenticated: 'auth-not-authenticated',
notAuthorized: 'auth-not-authorized'
})
.constant('USER_ROLES', {
all: '*',
admin: 'admin',
editor: 'editor',
guest: 'guest'
})
.directive('userLogin',
['$rootScope', '$window', '$timeout', '$http', '$location', 'solBackend', 'AUTH_EVENTS', 'USER_ROLES',
($rootScope, $window, $timeout, $http, $location, solBackend, AuthService, AUTH_EVENTS, USER_ROLES) => {
return {
restrict: 'E',
templateUrl: '/modules/user-login/user-login.html',
replace: true,
scope: true,
link: function ($scope, element, attrs) {
console.log('userLogin Directive: ', AUTH_EVENTS, $scope.isAuthenticated);
$scope.currentUser = false;
$scope.isAuthenticated = false;
$rootScope.currentUser = false;
$rootScope.isAuthenticated = false;
var cookie = false;
var value = "; " + document.cookie;
var parts = value.split("; " + 'tacsession' + "=");
if (parts.length == 2) cookie = parts.pop().split(";").shift();
console.log('cookie', cookie);
if (cookie.length > 10) {
$http.get('https://localhost.trackauthoritymusic.com/json/getme')
.then(function(res) {
if (res.data.error) {
console.log('tacsession failed', res.data.error);
} else if (res.data.user_id) {
$scope.setCurrentUser(res.data);
}
},
function(response) { // optional
console.log('cookie rejected', response);
});
}
// /json/getme > IF VALID set, ELSE reject
$scope.toggleGoogleAuth = () => {
if (!$scope.authenticated)
solBackend.authenticateWithPopup();
else
solBackend.unauthenticate();
};
solBackend.getAuth().then(($auth) => {
$auth.$onAuth((auth) => {
if (auth && auth.uid) {
$scope.authenticated = true;
$scope.authData = auth.google;
}
else {
$scope.authenticated = false;
}
});
});
}
};
}])
.factory('AuthService', function ($http, Session) {
var authService = {};
authService.login = function (credentials) {
function serializeParams(obj) {
var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
for(name in obj) {
value = obj[name];
if(value instanceof Array) {
for(i=0; i<value.length; ++i) {
subValue = value[i];
fullSubName = name + '[' + i + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
else if(value instanceof Object) {
for(subName in value) {
subValue = value[subName];
fullSubName = name + '[' + subName + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
else if(value !== undefined && value !== null)
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
}
return query.length ? query.substr(0, query.length - 1) : query;
};
return $http({
url: 'https://localhost.trackauthoritymusic.com/manage/users/login?tar=doAjax',
method: "POST",
dataType: 'json',
data: serializeParams(credentials)
})
.then(function(res) {
Session.create(res.data);
return res.data;
},
function(response) { // optional
console.log(response);
});
};
authService.isAuthenticated = function () {
console.log('checking isAuthenticated', Session);
return Session.user_id < 1;
};
authService.isAuthorized = function (role) {
console.log('question isAuthorized: ' + role, USER_ROLES);
return (authService.isAuthenticated() && typeof USER_ROLES[role] == 'object' && USER_ROLES[role] > 2);
};
return authService;
})
.factory('AuthResolver', function ($q, $rootScope, $state) {
return {
resolve: function () {
var deferred = $q.defer();
var unwatch = $rootScope.$watch('currentUser', function (currentUser) {
console.log('watching currentUser ', currentUser);
if (angular.isDefined(currentUser)) {
if (currentUser) {
console.log('currentUser defined');
deferred.resolve(currentUser);
} else {
deferred.reject();
$state.go('user-login');
}
unwatch();
}
});
return deferred.promise;
}
};
})
.service('Session', function () {
this.create = function (me) {
this.me = me;
this.user_id = parseInt(me.user_id);
this.user_status = parseInt(me.user_status);
};
this.destroy = function () {
this.me = null;
this.user_id = -1;
this.user_status = 0;
};
})
.controller('LoginController', function ($scope, $rootScope, AUTH_EVENTS, AuthService) {
console.log('LoginController: ', AUTH_EVENTS);
$scope.credentials = {
user_email: '',
password: ''
};
$scope.login = function (credentials) {
console.log('Sending credentials: ', $scope.credentials);
AuthService.login(credentials).then(function (user) {
$rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
$scope.setCurrentUser(user);
}, function () {
$rootScope.$broadcast(AUTH_EVENTS.loginFailed);
});
};
})
.config(function ($httpProvider) {
$httpProvider.interceptors.push([
'$injector',
function ($injector) {
return $injector.get('AuthInterceptor');
}
]);
})
.factory('AuthInterceptor', function ($rootScope, $q, AUTH_EVENTS) {
return {
responseError: function (response) {
$rootScope.$broadcast({
401: AUTH_EVENTS.notAuthenticated,
403: AUTH_EVENTS.notAuthorized,
419: AUTH_EVENTS.sessionTimeout,
440: AUTH_EVENTS.sessionTimeout
}[response.status], response);
return $q.reject(response);
}
};
});
app.run(function ($rootScope, AUTH_EVENTS, AuthService) {
console.log('RUNNING USER-LOGIN: ', AUTH_EVENTS);
$rootScope.$on('$stateChangeStart', function (event, next) {
console.log('state change start', next.data);
if (!AuthService.isAuthenticated()) {
event.preventDefault();
console.log('NOT AUTHENTICATED: ' + AUTH_EVENTS.notAuthenticated);
$rootScope.$broadcast(AUTH_EVENTS.notAuthenticated);
}
});
});
export default app;
ambiane-pane模块:
import 'angular';
export default angular.module('ambiance-pane',
['sol-backend', 'services', 'filters'])
.directive('ambiancePane',
['$rootScope', '$window', '$timeout', '$http', '$location', 'youtubeAPI', 'taAPI', 'playList', 'solBackend',
($rootScope, $window, $timeout, $http, $location, youtubeAPI, taAPI, playList, solBackend) => {
return {
restrict: 'E',
replace: true,
templateUrl: '/modules/ambiance-pane/ambiance-pane.html',
scope: {},
link: ($scope, $element) => {
console.log("AMBIANCE LINKED playList.playlist", playList.playlist, $scope.isAuthenticated);
Object.assign($scope, {
challenge_id:null,
active: false,
status: 'active',
users_count:0,
track_scount:0,
challenge_id:-1,
track_list:[],
track_order:{},
author_id:-1,
ta_id:-1
});
},
controller: function($scope, $element, $attrs) {
$scope.challenges = [{challenge_id:-1,challenge_title:"My custom playlist",group_id:-1}];
$scope.challenge = null;
$scope.selectedChallengeItem = [0];
$scope.currentUser = false;
$scope.isAuthenticated = false;
var cid = playList.getNowPlayingIdx();
var state = playList.getState();
console.log('ambiance-pane knows isAuthenticated', $scope.isAuthenticated);
if (true || $scope.isAuthenticated) {
taAPI.getChallenges().then(function(response) {
if (typeof response.popBody == 'object') {
console.log('ALL CHALLENGES: ', response);
var options = response.popBody;
options['_-1'] = {challenge_id:-1,challenge_title:"My custom playlist",group_id:-1};
$scope.challenges = options;
for(var i in response.popBody) {
$scope.selectedChallengeItem = response.popBody[i];
break;
}
if ($scope.selectedChallengeItem.challenge_id > 0) {
var cid = $scope.selectedChallengeItem.challenge_id;
taAPI.getTAplaylist(cid).then(function(response) {
console.log('GOT CHALLENGE: ', response);
$scope.challenge = response.popBody;
});
}
}
});
}
$scope.items = playList.playlist;
$scope.$watch(() => playList.metadata, (newVal, oldVal) => {
if (!!newVal) {
newVal.$bindTo($scope, "metadata");
} else {
$scope.metadata = null;
}
if (oldVal) {
oldVal.$destroy();
}
});
$scope.getChallenge = function(){
return $scope.challenge;
}
}
}
}])
.directive('challengeBlock', function ($compile) {
var definitions = {
restrict: 'E',
templateUrl: '/html/playlist/challengeBlock.html',
replace: true,
scope: true,
transclude:true,
link: function($scope, $element, $attrs) {
$scope.dataSources = {
ci: 'https://localhost.trackauthoritymusic.com',
angular: 'https://localplayer.trackauthoritymusic.com',
api : 'https://localhost.trackauthoritymusic.com'
}
}
};
return definitions;
});
调用所有其他人的应用程序模块:
[import '...whole project'];
const cacheUpdated = new Promise((resolve, reject) => {
if (window.hasOwnProperty('applicationCache')) {
window.applicationCache.addEventListener('updateready', function() {
resolve();
});
}
});
export default angular.module('Application', [..references..]).constant('DATA_SOURCES', {
ci: 'https://localhost.trackauthoritymusic.com',
angular: 'https://localplayer.trackauthoritymusic.com',
api : 'https://localhost.trackauthoritymusic.com'
}).directive('solarizdApp', ['$rootScope', 'ApiKey', 'playList', 'solBackend', function($rootScope, ApiKey, playList, solBackend) {
return {
restrict: 'E',
templateUrl: '/html/app.html',
replace: true,
scope: true,
link: function($scope, $element) {
$scope.currentUser = false;
$scope.isAuthenticated = false;
//$rootScope.currentUser = false; // doesn't help
//$rootScope.isAuthenticated = false;
$scope.setCurrentUser = function (user) {
console.log("setting global user", user);
$scope.currentUser = user;
if (user.user_id > 0) {
$scope.isAuthenticated = user.group_user_status;
}
};
ApiKey.fetchKeys().then(function() {
$element[0].classList.add('loaded');
});
// Notify users when there's a new version
cacheUpdated.then(() => {
$rootScope.$broadcast('toast::notify', {
text: 'Reload this app to get a newer version',
persist: true
});
});
},
controller : function($scope, $rootScope) {
console.log('solarizdApp controller');
$scope.currentUser = false;
$scope.isAuthenticated = false;
$scope.setCurrentUser = function (user) {
console.log("setting global user from controller", user);
$scope.currentUser = user;
if (user.user_id > 0) {
$scope.isAuthenticated = user.group_user_status;
}
};
}
};
}])
.config(["$httpProvider", function($httpProvider) {
$httpProvider.interceptors.push('middleware');
}]).factory('middleware', function() {
return {
request: function(config) {
if (config.url.indexOf("trackauthoritymusic.com") > -1) {
console.log("HTTP REQUEST", config);
if (!config.headers || typeof config.headers != 'object') {
console.log('instantiating headers???');
config.headers = {};
}
config.withCredentials = true;
config.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
}
return config;
}
};
});
答案 0 :(得分:1)
您可以在所有三个模块标签中执行此操作,这将产生类似的解决方案。
可能的方法:
单独使用 ng-if 作为
<sol-tabs id="main-vifirstew" data-loggedin="{{isAuthenticated}}" selected="{{defaultTab}}">
<dashboard-pane
ng-if="isAuthenticated"
tab-icon="ambiance" ></dashboard-pane>
<user-login
ng-if="isAuthenticated"
tab-icon="login" ></user-login>
<third-pane tab-icon="search"></third-pane>
<fourth-pane tab-icon="list-ol"></fourth-pane>
</sol-tabs>
单独使用ng-show
<sol-tabs id="main-vifirstew" data-loggedin="{{isAuthenticated}}" selected="{{defaultTab}}">
<dashboard-pane
ng-show="isAuthenticated"
tab-icon="ambiance" ></dashboard-pane>
<user-login
ng-show="isAuthenticated"
tab-icon="login" ></user-login>
<third-pane tab-icon="search"></third-pane>
<fourth-pane tab-icon="list-ol"></fourth-pane>
</sol-tabs>
最后,使用ng-hide
<sol-tabs id="main-vifirstew" data-loggedin="{{isAuthenticated}}" selected="{{defaultTab}}">
<dashboard-pane
ng-show="isAuthenticated"
tab-icon="ambiance" ></dashboard-pane>
<user-login
ng-show="isAuthenticated"
tab-icon="login" ></user-login>
<third-pane tab-icon="search"></third-pane>
<fourth-pane tab-icon="list-ol"></fourth-pane>
</sol-tabs>
最佳实践
使用 ng-if 。
<强>为什么吗
只有满足条件才会检索特定元素,因此您的浏览器可能不会在开发人员工具中显示标记
如果元素包含某些数据,则仅在满足条件时才加载的图像
希望这会对你有所帮助。
答案 1 :(得分:0)
我会将sol-tabs
标记的内容移到指令的模板中,并将其结构如下:
<div ng-if="isAuthenticated">
<dashboard-pane tab-icon="ambiance"></dashboard-pane>
</div>
<div ng-if="isAuthenticated">
<user-login tab-icon="login" ></user-login>
</div>
...
因此ng-if
指令不在自定义指令上。
从我所看到的情况来看,直接在自定义指令标签中使用ng-if或ng-show会使其表现得很奇怪,我猜是因为范围。
然后在主视图中使用sol-tabs
这样的内容:
<sol-tabs id="main-vifirstew" is-authenticated="isAuthenticated" data-loggedin="{{isAuthenticated}}" selected="{{defaultTab}}"></sol-tabs>