我有两个与父子关系相关的组件。父组件的 ngOnInit 方法检查用户是否登录,如果未登录,则导航到登录页面。
class ParentComponent implements OnInit{
ngOnInit(){
if(!authService.loggedIn){
//navigate to login screen code
return;
}
}
}
class ChildComponent implements OnInit{
ngOnInit(){
/** POINT TO BE NOTED **/
// this function is also called even if ngOnInit
// of parent navigates to different component and returns.
// do some stuff with userService.token
// but because token isn't available the calls fail
}
}
Run Code Online (Sandbox Code Playgroud)
如果父组件想要导航到其他组件,如何阻止此级联 OnInit 调用?
我已经在我的应用程序上实现了 Route Guards。在用户访问仪表板路由之前,我检查了用户是否已登录。
登录后用户访问仪表板工作正常,但如果用户尝试在未登录的情况下访问路线仪表板,则会出现空白页面。CanActivate Guard 被执行并返回 false。
但是,如果 CanActivate 失败,我想将用户重定向到日志记录页面。
如果 Route Guard 失败,如何将用户重定向到另一个路由?
这就是我所遵循的
import { Routes, RouterModule } from '@angular/router';
import { AccountPage } from './account-page';
import { LoginRouteGuard } from './login-route-guard';
import { SaveFormsGuard } from './save-forms-guard';
const routes: Routes = [
{ path: 'home', component: HomePage },
{
path: 'accounts',
component: AccountPage,
canActivate: [LoginRouteGuard],
canDeactivate: [SaveFormsGuard]
}
];
export const appRoutingProviders: any[] = [];
export const routing = RouterModule.forRoot(routes);Run Code Online (Sandbox Code Playgroud)
import { CanActivate } from '@angular/router';
import …Run Code Online (Sandbox Code Playgroud)我目前正在努力改善我的用户体验。当用户切换到新组件时,大约需要 0.5 到 1 秒的时间才能加载数据并显示在视图中。因此,在最初的时刻,视图是空的,某些部分丢失或显示错误。
我知道有角度解析接口。然而,据我了解,这只是延迟视图的渲染,直到数据可用。
我想知道是否有一个选项,您可以在渲染我的应用程序的登陆页面后在后台加载数据。这样,用户就可以在后台使用和查看应用程序,而不会注意到正在加载其他页面/组件的数据。
或者也许有更好的方法,或者我对解析接口的理解是错误的。
编辑: 提供一个示例,说明我的代码当前如何工作:在服务文件中:
getTiers () {
return this.http.get(this.authService.getApiEndpoint(), this.authService.getRequestOptions())
.map(
(response: Response) => {
const data = response.json();
return data;
}
);
Run Code Online (Sandbox Code Playgroud)
在我的组件文件中: ngOnInit() { this.getTiers();
}
getTiers () {
this.tierService.getTiers()
.subscribe(
(tiers) =>
this.tiers = tiers.data,
(error) => console.log(error),
() => this.initializingCompleted = true
);
}
Run Code Online (Sandbox Code Playgroud)
在我的模板文件中:
<div class="col-md-4" *ngFor="let tier of tiers">
<ul class="table">
<li class="title">
{{ tier.title }}
</li>
[...]
Run Code Online (Sandbox Code Playgroud) 如何使用 karma 测试 jasmine 中的 forEach 循环?组件代码如下:-
getData(studentsList:any, day:any, game:any){
let strength:any;
let location:string;
if(studentsList){
studentsList.forEach( value => {
strength=value.schedule[day][game].strength;
location=value.schedule[day][game].location;
});
}
}
Run Code Online (Sandbox Code Playgroud)
StudentsList 中存在的数据是:-
(编辑:-数据已更新,看起来像这样)
[{
"activityName": "tournament1",
"schedule": {
"first": {
"Baseball": {
"strength": 23,
"location": "abc"
}
},
"second": {
"Cricket": {
"strength": 20,
"location": "bcd"
}
},
"third": {
"Football": {
"strength": 19,
"location": "cde"
}
}
}
},
{
"activityName": "tournament2",
"schedule": {
"first": {
"Baseball": {
"strength": 23,
"location": "abc"
}
},
"second": …Run Code Online (Sandbox Code Playgroud) 对我来说使用嵌套路由的原因是动态处理每个页面的图标和后退按钮。我有抽象路由,因为当我单击后退按钮时,路由参数消失,我放置一个抽象路径来保留id并questionnaire在 url 中键入参数。我的抽象路径是Questionaire
{ path: 'Home', component: HomeComponent,data:{icon:'fa-home'} },
{ path: 'QuestionaireList', component: QuestionaireListComponent,data:{icon:'fa-list-ul',previousState:'/Home'} },
{
path: 'Questionaire/:questionnaireType/:id',
children:[
{ path: 'AddQuestionnaire', component: CreateQuestionnaireComponent,data:{icon:'fa-plus',previousState:'/QuestionaireList'} },
{ path: 'UpdateQuestionnaire', component: EditComponent,data:{icon:'fa-pencil',previousState:'/QuestionaireList'} },
{ path: 'QuestionList', component: QuestionListComponent,data:{icon:'fa-pencil',previousState:'/QuestionaireList'} },
{ path: 'ImportQuestion', component: ImportQuestionComponent,data:{icon:'fa-plus',previousState:'/QuestionaireList'} },
{ path: 'MetaContentList', component: MetaContentListComponent,data:{icon:'fa-database',previousState:'/QuestionaireList'} },
{ path: 'ModifyMetaContent/:metaContentId/:title', component: ModifyMetaContentComponent,data:{icon:'fa-database',previousState:'/MetaContentList'}},
]}
Run Code Online (Sandbox Code Playgroud)
另外,在questionnaire.list.html我通过 routerlink 链接到每条路径时,下面是我的链接:
[routerLink]="['/Questionaire',item.questionnaireType,item.id,'/UpdateQuestionnaire']"
Run Code Online (Sandbox Code Playgroud)
这是我的链接:
<a class="primary small ui icon button" [routerLink]="['/Questionaire',item.questionnaireType,item.id,'/UpdateQuestionnaire']" >
<i class="edit icon"></i>
</a>
Run Code Online (Sandbox Code Playgroud)
我预计当我点击链接时我会路由到这个地址: …
我想向作为我的应用程序引导程序的组件发出一个事件。该组件是 websocket 连接的处理程序,我需要发送一条消息,这就是我必须发出此事件的原因。
在引导组件中,我只有<router-outlet></router-outlet>这样我无法意识到如何接收事件。
例子
应用程序组件.html
<router-outlet></router-outlet>
应用程序组件.ts
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
}
Run Code Online (Sandbox Code Playgroud)
应用程序模块.ts
...
@NgModule({
...
bootstrap: [AppComponent]
})
Run Code Online (Sandbox Code Playgroud)
应用程序路由.module.ts
...
const routes: Routes = [
{ path: 'display', component: MapDisplayComponent }
];
Run Code Online (Sandbox Code Playgroud)
地图显示.components.ts
@Component({
selector: 'app-map-display',
templateUrl: './map-display.component.html',
styleUrls: ['./map-display.component.scss']
})
export class MapDisplayComponent {
@Output() sendMessage: EventEmitter<any> = new EventEmitter<any>();
}
Run Code Online (Sandbox Code Playgroud)
所以问题是地图显示组件必须将事件发送给他的父组件
我在ngOnInitcontroller.ts 中订阅了一种方法。从视图中,有一个选项可以从列表中选择不同的用户,这些用户重定向到同一页面,只是 URL 中的 ID 发生了变化。因此ngOnInit被多次调用。因此方法被多次订阅。我们多次选择不同的用户方法被调用为每个选择的成员数量,即如果我们选择 3 个用户一个接一个的路由被更改 3 次因此当 observable 获得结果时方法被调用 3 次。但是如果我们刷新页面一切正常。但是如果我使用 unsubscribe inngDestroy那么它就不会在ngOnInit. 有什么解决办法吗。
ngOnInit() {
this._myService.detailsReceived.subscribe((obj: details) =>
{console.log(obj.text)}
);
}
Run Code Online (Sandbox Code Playgroud)
同一页面上的路线变化是
this.route.navigate(['user-home', userid]);
Run Code Online (Sandbox Code Playgroud)
我需要这种方法保持订阅直到用户注销,因此不能使用 subscribe.Take(1)
我在访问内部订阅的变量时遇到问题。在这里,我包含代码,在 ngOninit 中,我有返回对象的服务,从该对象,我可以获取我想要的 json,然后我尝试将其存储在一个变量中,然后我尝试在外部访问该变量订阅我做不到。那么我如何在订阅之外使用变量呢?
ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
this.dataService.GetFormById(+id).subscribe(response => {
console.log(response);
const temp = response['TemplateJson'];
var Data = temp;
})
initJq();
var formData = Data
this.formBuilder = (<any>jQuery('.build-wrap')).formBuilder({ formData });
// Sample code to handle promise to get for data on page load directly
this.formBuilder.promise.then(formBuilder => {
console.log(formBuilder.formData);
});
}
Run Code Online (Sandbox Code Playgroud)
在 subscribe 内的这段代码中,有变量 Data,在 temp 中我有 json,那么我如何将该数据存储在 formData 变量中。
我有这个带有routerLink指令的按钮,当我点击它时它工作正常:
<button type="button" class="btn btn-secondary" [routerLink]="['/companies', id, 'departments', 'edit', t.id]">Edit department</button>
Run Code Online (Sandbox Code Playgroud)
那我有这个超链接:
<a class="nav-link" routerLink="['/companies', id, 'departments']" routerLinkActive="active">Show departments</a>
Run Code Online (Sandbox Code Playgroud)
当我将鼠标悬停在其上时,创建的网址并不是我所期望的.
我有的网址: http://localhost:4200/#/%5B'/companies'%2C%20id%2C%20'departments'%5D
1.)为什么routerLink创建的链接/ url的输出不同?这两种方案都必须创建一个有效/可用的URL才能导航到.
2.)我该如何解决这个问题?
在显示当前配置文件的"ProfileComponent"中,有一个其他配置文件的列表,因此当我尝试通过...导航到另一个配置文件时
this.router.navigate(['/profile/' + profileID]);
Run Code Online (Sandbox Code Playgroud)
它改变了url中的params http://localhost:4200/profile/fsfterthjkj5
至 http://localhost:4200/profile/hj45k35v
但该组件保持显示相同的配置文件.我可以通过简单地将新配置文件分配给旧配置文件来重新渲染组件,并且角度更新页面上的所有数据但是...我如何这样做我可以通过单击"返回"按钮返回旧配置文件在浏览器中.
我尝试在params更改后重新加载页面 - 这种方式也会渲染我需要的配置文件但仍然无法返回,params只是更改url并且对页面没有任何影响,并且没有任何意义请求相同的数据之后已加载时重新加载.
angular2-routing ×10
angular ×9
javascript ×2
angular5 ×1
angular7 ×1
angularjs ×1
eventemitter ×1
ngoninit ×1
observable ×1
subscribe ×1