我试图找出为什么下面的 router.navigate(['']) 代码不将用户带到登录组件。我只停留在家庭组件上。当我添加调试器时;从代码来看,它似乎进入了某种无限循环。
流程如下: 由于 Route Guard 失败,用户来到站点并立即被重定向到 /login。如果他们登录,Route Guard 就会通过并转到 [' '],即 HomeComponent。然后,当他们单击注销时,我认为导航到 [' '] 应该会失败,只需转到 /login。由于某种原因,它停留在 HomeComponent 上并且从不导航。
home.component.ts
logout() {
this.userService.logout();
this.router.navigate(['']);
}
Run Code Online (Sandbox Code Playgroud)
用户服务.ts
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url;
return this.verifyLogin(url);
}
verifyLogin(url: string): boolean {
if (this.userLoggedIn) { return true; }
this.router.navigate(['/login']);
return false;
}
logout() {
this.userLoggedIn = false;
}
Run Code Online (Sandbox Code Playgroud)
应用程序路由.module.ts
const routes: Routes = [
{ path: '' , component: HomeComponent, canActivate: [UserService]},
{ path: 'login', component: LoginComponent …Run Code Online (Sandbox Code Playgroud) javascript typescript angular-routing angular-components angular
我对 Angular 5 完全陌生,我想在应用程序打开时显示登录页面。
现在我显示 appComponent,它有工具栏和侧面导航栏。但是当用户加载应用程序时,如果登录成功,我想显示登录屏幕,那么只有用户应该允许查看主页。
如果我将我的应用程序组件作为登录组件,我无法根据用户的菜单选择在主页中加载不同的组件。
应用程序组件.html
<mat-sidenav-container fullscreen>
<mat-sidenav #sidenav class="app-sidenav">
<mat-nav-list>
<a mat-list-item routerLink="/home" routerLinkActive="active-list-item">
<h2 matLine>Home</h2>
<mat-icon matListIcon>home</mat-icon>
</a>
<a mat-list-item routerLink="/account" routerLinkActive="active-list-item">
<h2 matLine>Account</h2>
<mat-icon matListIcon>person</mat-icon>
</a>
<a mat-list-item routerLink="/settings" routerLinkActive="active-list-item">
<h2 matLine>Settings</h2>
<mat-icon matListIcon>settings</mat-icon>
</a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<mat-toolbar color="primary" class="mat-elevation-z3">
<button mat-icon-button (click)="sidenav.toggle()">
<mat-icon>menu</mat-icon>
</button>
My App
</mat-toolbar>
<div class="app-content">
<router-outlet></router-outlet> // router-outlet
</div>
</mat-sidenav-content>
</mat-sidenav-container>
Run Code Online (Sandbox Code Playgroud)
目前,当我运行应用程序时,正在加载此页面。我想显示全屏登录页面,而不是首先显示主页。
const routings: Routes = [
{path:'',redirectTo:'/app-root',pathMatch:'full'},
{path:'home',component:HomeComponent},
{path:'account',component:AccountComponent},
{path:'settings',component:SettingsComponent},
{path:'**',redirectTo:'/app-root',pathMatch:'full'},
];
Run Code Online (Sandbox Code Playgroud)
目前,当 url 为 ' ' …
如何使用组件作为 Angular 中另一个组件的输入数据?
\n\n例如:
\n\n我想要构建表格组件AppTableComponent:
\n\n<app-table [dataSource]="dataSource" [columns]="columns">\n <ng-container tableColumnDef="actions">\n <a routerLink="/model/edit/{{item.id}}" routerLinkActive="active">Edit</a>\n <a routerLink="/model/delete/{{item.id}}" routerLinkActive="active">Delete</a>\n </ng-container>\n <ng-container tableColumnDef="isActive">\n <div [ngClass]="{cercl:true, \'is-active\':item.is_active}"> </div>\n </ng-container>\n</app-table>\nRun Code Online (Sandbox Code Playgroud)\n\ndataSource是数据数组之和,如Model[]orPerson[]或Car[]。columns是一个字符串数组,如[\'id\', \'isActive\', \'name\', \'actions\']. 它应该包含数据源行属性名称或附加列名称。
我知道如何使用ng-content,但它不是相同的情况。不同之处在于我应该在多个地方使用部分内容。也许我应该使用 ng-contet,但我不知道\xe2\x80\x99t 是什么。
我确信我的目标是可能的,因为 Angular 材质表的工作原理如下:
\n\n<mat-table #table [dataSource]="dataSource">\n <ng-container matColumnDef="position"></ng-container>\n <ng-container matColumnDef="weight"></ng-container>\n</mat-table>\nRun Code Online (Sandbox Code Playgroud)\n\n请不要建议我使用 Angular 材料表组件。我不需要桌子。我只是想学点新东西。
\n\n我将非常感谢有关该主题的任何信息或文章!
\n编辑:我的解决方案是重新思考我想要实现的目标,而不是尝试创建一个从不同来源获取参数和数据然后在父级中多次调用的组件,我制作了一个仅使用网格的组件布局(材质网格),然后它包含所有模板标记和 API 调用,并在父级中调用一次。我认为这更容易维护,但不能在另一个仪表板中重用,除非我扩展它并在模板中使用 *ngIf。
我有一个仪表板,它将显示来自组件中 API 的不同数据列表,否则每个实例的数据列表都是相同的。
我能够创建该组件并在父级中使用它,并且可以提供基本的替代方案,例如图标旁边的标题文本,但我无法弄清楚如何为每个实例引用来自 API 的不同数据集。当我调用它时的组件。
如何创建一个可重用组件来接受与其他实例不同的数据并使用模板显示它?
我找到了一些关于如何重用组件的教程,但这不是我需要的。我考虑在模板中使用多个来*ngIf测试和显示/隐藏显示哪组数据,从而拥有一个具有多个变体的大型组件,但这看起来很混乱,并且具有多种用途将很难维护。
如您所见,我可以更改标题文本和图标等简单的内容,但数据需要更复杂的结构,每个实例的结构都不相同。
可重用的组件模板
<mat-card class="panel">
<header class="subheader">
<h2><mat-icon color="primary">{{iconRef}}</mat-icon> {{headerRef}}</h2>
<hr class="header">
</header>
// a table or list of data here, changes for each use.
// Will use for example {{ data.activity }} from one endpoint
// or {{ data2.location }} from some other endpoint
</mat-card>
Run Code Online (Sandbox Code Playgroud)
在父级中使用如下:
<app-resusable-dash-one [headerRef]="' Prosjekt'" [iconRef]="'assignment'"></app-resusable-dash-one>
Run Code Online (Sandbox Code Playgroud)
可重用组件.ts:
export class ResusableDashOneComponent implements OnInit {
@Input() iconRef: string;
@Input() headerRef: string;
dataRef: any[] = …Run Code Online (Sandbox Code Playgroud) 我有一个反应形式。设置与此类似:
myForm: FormGroup;
this.myForm= new FormGroup({
name: new FormControl("", [Validators.required, Validators.maxLength(15), Validators.pattern('...')]),
...
});
Run Code Online (Sandbox Code Playgroud)
我在我的表单上使用它,如下所示:
<input
type="text"
formControlName="name"
/>
<div *ngIf="name.errors?.required">
Name is required
</div>
<div *ngIf="name.errors?.maxlength">
Name must be {{ name.errors.maxlength.requiredLength }} characters
</div>
<div *ngIf="name.errors?.pattern">
Name has invalid characters.
</div>
Run Code Online (Sandbox Code Playgroud)
这只是我表格的精简版。我有多个输入,我不得不为每个输入创建错误 div。
所以为了解决这个问题,我尝试创建一个组件。该组件与上面的代码非常相似:
<input
type="text"
[formControlName]="formControlName"
/>
<div *ngIf="name.errors?.required">
Name is required
</div>
etc...
Run Code Online (Sandbox Code Playgroud)
.ts 文件:
@Component({
selector: 'app-text',
templateUrl: './text.component.html'
})
export class TextComponent {
@Input() formControlName: FormControl;
}
Run Code Online (Sandbox Code Playgroud)
所以在我的表单上,我想使用这个组件如下:
<app-text [formControlName]="name"></app-text>
Run Code Online (Sandbox Code Playgroud)
但是我不能让它与 formControlName 属性一起使用。
这可能吗?
谢谢 …
angular-components angular angular-reactive-forms controlvalueaccessor
我在一个项目中使用 Angular 8,并且在启动动态组件时遇到问题,因为 ngOnInit 没有被调用。我构建了一个名为 PlaceholderDirective 的指令,如下所示:
@Directive({
selector: '[appPlaceholder]'
})
export class PlaceholderDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
Run Code Online (Sandbox Code Playgroud)
并在 ng-template 上使用该指令:
<ng-template appPlaceholder></ng-template>
Run Code Online (Sandbox Code Playgroud)
保存 ng-template 所在 HTML 的组件启动动态组件,如下所示:
@ViewChild(PlaceholderDirective, {static: false}) private placeholder: PlaceholderDirective;
...
constructor(private componentResolver: ComponentFactoryResolver) {}
...
public launchSensorEditComponent(id: number) {
const componentFactory = this.componentResolver.resolveComponentFactory(SensorEditComponent);
const hostViewContainerRef = this.placeholder.viewContainerRef;
hostViewContainerRef.clear();
const sensorEditComponentRef = hostViewContainerRef.createComponent(componentFactory);
sensorEditComponentRef.instance.sensorId = id;
}
Run Code Online (Sandbox Code Playgroud)
实际的动态组件非常简单,它注册在AppModule的entryComponents部分中。我已将其范围缩小到最低限度,以便了解问题所在:
@Component({
selector: 'app-sensor-edit',
templateUrl: './sensor-edit.component.html',
styleUrls: ['./sensor-edit.component.css']
})
export class SensorEditComponent implements OnInit {
@Input() sensorId: …Run Code Online (Sandbox Code Playgroud) angular-components angular angular-dynamic-components angular-lifecycle-hooks
在另一个组件中注入组件来访问注入组件中的函数或属性是否正确?
注意:这些组件都不是另一个组件的子组件
import { UsersComponent } from './../users/users.component';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
constructor(users:UsersComponent){
users.getAllUsers()
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个需要输入的组件.. @Input() coDeliveryCandidates: DeliverySlotView[];
这在模板中使用:
<ng-container *ngFor="let coDeliverySlotView of (coDeliveryCandidates | async)">
<button
mat-raised-button
[color]=""
>
{{ label }}
</button>
</ng-container>
Run Code Online (Sandbox Code Playgroud)
color 属性需要一个字符串作为值,我想做一些类似的事情:
[color]="{
black: coDeliverySlotView.slotId === bookedSlot.slotId,
grey: !coDeliverySlotView.slotId === bookedSlot.slotId
}"
Run Code Online (Sandbox Code Playgroud)
在这里,我使用与 ngClass 相同的语法,但我想它不支持这种方式..那么还有哪些其他类似的方式呢?:)
conditional-statements angular-material angular-components angular
我试图在导航中突出显示您滚动过去的活动片段。
将片段和导航添加到片段很简单并且效果很好,例如:
class="nav-button unselectable"
matRipple
routerLink="/"
fragment="features"
[ngClass]="{ 'nav-active': (active_fragment | async) === 'features' }"
Run Code Online (Sandbox Code Playgroud)
但是路由器显然不知道你在滚动哪个元素,所以我试图监听滚动事件并使用 Y 位置检查最近的元素。
但是我的登陆页面不是我的导航的子页面,所以 viewchild 不起作用,例如:
导航组件:
@ViewChild('features', { static: false })
private _features: ElementRef;
@HostListener('window:scroll', ['$event'])
private _update_active_fragment(event: any) {
event.preventDefault();
console.log(window.pageYOffset);
console.log(this._features.nativeElement);
}
Run Code Online (Sandbox Code Playgroud)
登陆页面组件:
<app-features #features id="features"></app-features>
Run Code Online (Sandbox Code Playgroud)
但是特性原生元素是未定义的。
我的问题是:
如何一次性替换或更改旧的组件前缀?
或者
如何使前缀动态化,以便每当想要更改它时都会更新所有组件前缀?
angular-components angular angular-library angular8 angular9