在不同组件中使用服务不工作
Consume service in different components not working
我有一个侧面导航栏和一个内容 div。我目前想要实现的是,每当我点击侧边导航中的任何元素时。该导航项的 innerText 应显示在内容 div 中。我的代码如下
sidenav.component.ts
import {Component} from '@angular/core';
import {FlatTreeControl} from '@angular/cdk/tree';
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material';
import {BlogService} from '../../../../services/blog.service';
interface FoodNode {
name: string;
children?: FoodNode[];
}
const TREE_DATA: FoodNode[] = [
{
name: 'Fruit',
children: [
{name: 'Apple'},
{name: 'Banana'},
{name: 'Fruit loops'},
]
}, {
name: 'Vegetables',
children: [
{
name: 'Green',
children: [
{name: 'Broccoli'},
{name: 'Brussel sprouts'},
]
}, {
name: 'Orange',
children: [
{name: 'Pumpkins'},
{name: 'Carrots'},
]
},
]
},
];
interface ExampleFlatNode {
expandable: boolean;
name: string;
level: number;
}
@Component({
selector: 'app-sidenav',
templateUrl: './sidenav.component.html',
styleUrls: ['./sidenav.component.css'],
providers: [BlogService]
})
export class SidenavComponent {
treeControl = new FlatTreeControl<ExampleFlatNode>(
node => node.level, node => node.expandable);
private transformer = (node: FoodNode, level: number) => {
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level,
};
}
treeFlattener = new MatTreeFlattener(
this.transformer, node => node.level, node => node.expandable, node => node.children);
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
constructor(private blogService: BlogService) {
this.dataSource.data = TREE_DATA;
}
hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
routeToPage(event: any) {
this.blogService.changeSelectedNode(event.target.innerText);
}
}
content.component.ts
import {Component, OnInit} from '@angular/core';
import {BlogService} from '../../../../services/blog.service';
@Component({
selector: 'app-content',
templateUrl: './content.component.html',
styleUrls: ['./content.component.css'],
providers: [BlogService]
})
export class ContentComponent implements OnInit {
page: string;
constructor(private blogService: BlogService) {
this.page = this.blogService.selectedNodeName;
console.log(this.page);
}
ngOnInit() {
}
}
blog.service.ts
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs';
@Injectable()
export class BlogService {
public selectedNodeName: string;
public sideNavToggle: boolean;
public selectedNode: Subject<string> = new Subject<string>();
public sideNavDisabled: Subject<boolean> = new Subject<boolean>();
constructor() {
this.selectedNode.subscribe((node) => {
this.selectedNodeName = node;
});
}
changeSelectedNode(node: string) {
this.selectedNode.next(
this.selectedNodeName = node
);
}
}
请帮我解决这个问题。我能够成功地将内容传递给服务,但每次单击侧边导航项时内容 ts 文件中的代码都不会执行。
我的完整代码可以在这里找到 - https://stackblitz.com/github/vibhorgoyal18/atest-blog
我花了一段时间,但这里是您的示例更新和工作:Demo
这是我更改的内容:
首先你的服务定义不正确。您在 SideNavComponent 和 ContentComponent 中添加了诸如 [providers: BlogService] 之类的服务。这些组件随后没有获得相同的 BlogService 实例,因此它不起作用。您必须将提供者:[BlogService] 放入 AppModule。
第二:我删除了您在服务中订阅的部分,并将其移至 ContentComponent。否则 Angular 不会正确绑定到该变量。
编辑:
如果您使用的是 Angular 6+,您还可以将其添加到您的服务中并将其从模块中的提供程序中删除:
@Injectable({
providedIn: 'root'
})
这会在您的所有应用中提供该服务。如果你只想在一个模块中提供服务,你可以指定那个模块代替root。
我有一个侧面导航栏和一个内容 div。我目前想要实现的是,每当我点击侧边导航中的任何元素时。该导航项的 innerText 应显示在内容 div 中。我的代码如下
sidenav.component.ts
import {Component} from '@angular/core';
import {FlatTreeControl} from '@angular/cdk/tree';
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material';
import {BlogService} from '../../../../services/blog.service';
interface FoodNode {
name: string;
children?: FoodNode[];
}
const TREE_DATA: FoodNode[] = [
{
name: 'Fruit',
children: [
{name: 'Apple'},
{name: 'Banana'},
{name: 'Fruit loops'},
]
}, {
name: 'Vegetables',
children: [
{
name: 'Green',
children: [
{name: 'Broccoli'},
{name: 'Brussel sprouts'},
]
}, {
name: 'Orange',
children: [
{name: 'Pumpkins'},
{name: 'Carrots'},
]
},
]
},
];
interface ExampleFlatNode {
expandable: boolean;
name: string;
level: number;
}
@Component({
selector: 'app-sidenav',
templateUrl: './sidenav.component.html',
styleUrls: ['./sidenav.component.css'],
providers: [BlogService]
})
export class SidenavComponent {
treeControl = new FlatTreeControl<ExampleFlatNode>(
node => node.level, node => node.expandable);
private transformer = (node: FoodNode, level: number) => {
return {
expandable: !!node.children && node.children.length > 0,
name: node.name,
level,
};
}
treeFlattener = new MatTreeFlattener(
this.transformer, node => node.level, node => node.expandable, node => node.children);
dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
constructor(private blogService: BlogService) {
this.dataSource.data = TREE_DATA;
}
hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
routeToPage(event: any) {
this.blogService.changeSelectedNode(event.target.innerText);
}
}
content.component.ts
import {Component, OnInit} from '@angular/core';
import {BlogService} from '../../../../services/blog.service';
@Component({
selector: 'app-content',
templateUrl: './content.component.html',
styleUrls: ['./content.component.css'],
providers: [BlogService]
})
export class ContentComponent implements OnInit {
page: string;
constructor(private blogService: BlogService) {
this.page = this.blogService.selectedNodeName;
console.log(this.page);
}
ngOnInit() {
}
}
blog.service.ts
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs';
@Injectable()
export class BlogService {
public selectedNodeName: string;
public sideNavToggle: boolean;
public selectedNode: Subject<string> = new Subject<string>();
public sideNavDisabled: Subject<boolean> = new Subject<boolean>();
constructor() {
this.selectedNode.subscribe((node) => {
this.selectedNodeName = node;
});
}
changeSelectedNode(node: string) {
this.selectedNode.next(
this.selectedNodeName = node
);
}
}
请帮我解决这个问题。我能够成功地将内容传递给服务,但每次单击侧边导航项时内容 ts 文件中的代码都不会执行。
我的完整代码可以在这里找到 - https://stackblitz.com/github/vibhorgoyal18/atest-blog
我花了一段时间,但这里是您的示例更新和工作:Demo
这是我更改的内容:
首先你的服务定义不正确。您在 SideNavComponent 和 ContentComponent 中添加了诸如 [providers: BlogService] 之类的服务。这些组件随后没有获得相同的 BlogService 实例,因此它不起作用。您必须将提供者:[BlogService] 放入 AppModule。
第二:我删除了您在服务中订阅的部分,并将其移至 ContentComponent。否则 Angular 不会正确绑定到该变量。
编辑: 如果您使用的是 Angular 6+,您还可以将其添加到您的服务中并将其从模块中的提供程序中删除:
@Injectable({
providedIn: 'root'
})
这会在您的所有应用中提供该服务。如果你只想在一个模块中提供服务,你可以指定那个模块代替root。