[英]Angular 5 - change variable from another Component
I have a ParentComponent
with a ChildComponent
that contains another ChildComponent
( ResultList
in a sidebar)我有一个带有
ChildComponent
的ParentComponent
,其中包含另一个ChildComponent
(侧栏中的ResultList
)
In the ParentComponent
I open a dialog with a similar ResultList
from the sidebar- technically it is the same component - but it has more items.I try to select some of the values in the dialog and then I want to push them to the first ResultList
in the sidebar again.在
ParentComponent
我从侧边栏中打开一个带有类似ResultList
的对话框——从技术上讲,它是同一个组件——但它有更多的项目。我尝试在对话框中选择一些值,然后我想将它们推送到第一个ResultList
再次在侧边栏中。
Now I'm trying to pass the resultList
variable to each component to get my list updated in the sidebar, but it seems a little bit complex.现在我正在尝试将
resultList
变量传递给每个组件,以便在侧边栏中更新我的列表,但这似乎有点复杂。
If you (hopefully) unterstand my problem - Do you have any other ideas how can I update my sidebarcomponent from the modal dialog?如果您(希望)理解我的问题 - 您还有其他想法如何从模态对话框更新我的侧边栏组件?
If you have further questions - please ask :)如果您有其他问题 - 请询问:)
I'd recommend using a Service
with a BehaviorSubject
exposed asObservable
and subscribe
ing to it in all the components where you want to get the updated resultList
我建议使用将
BehaviorSubject
公开为asObservable
的Service
,并在要获取更新的resultList
所有组件中subscribe
该resultList
So you'll have a service: 因此,您将获得服务:
import { BehaviorSubject, Observable } from 'rxjs';
...
export class ResultListService {
private resultList: BehaviorSubject<any[]> = new BehaviorSubject<any[]>(null);
public resultList$: Observable<any[]> = this.resultList.asObservable();
updateResultList(updatedList) {
this.resultList.next(updatedList);
}
}
In the dialog component, you'll use the updateResultList
method and pass it the updatedResultList: 在对话框组件中,您将使用
updateResultList
方法,并将updateResultList
方法传递给它:
constructor(..., private resultListService: ResultListService) {}
...
this.resultListService.updateResultList(updatedResultList);
Now in any component where you want the updated resultList
, just subscribe
to resultList$
from ResultListService
: 现在,在您想要更新的
resultList
任何组件中,只需从ResultListService
subscribe
resultList$
:
constructor(..., private resultListService: ResultListService) {}
...
this.resultListService.resultList$
.subscribe(resultList => console.log('This is the updated resultList: ', resultList));
There are other options besides chaining @Input and @Output parameters through multiple components or using a service (which is likely the best solution if you are new to Angular), one of which is making use of shared state. 除了通过多个组件或使用服务来链接@Input和@Output参数之外,还有其他选择(如果您是Angular的新手,这可能是最佳解决方案),其中之一是利用共享状态。
Using a state management framework such ngrx , ngxs or akita allows you to share both state and changes to that state between components - in this case arrays and changes to their content. 使用诸如ngrx , ngxs或akita之类的状态管理框架,您可以在组件之间共享状态和对该状态的更改-在这种情况下,是数组及其内容的更改。
Once set up the store would manage adding the items selected in your child component to the array referenced in the parent component. 设置完成后,商店将设法将在子组件中选择的项目添加到父组件中引用的数组中。 The two components would not even have to be related to each other.
这两个组成部分甚至不必相互关联。
These two tutorials for ngrx and ngxs both cover a use case similar to yours. 这两个有关ngrx和ngxs的教程都涵盖了与您相似的用例。 The fact that you are using a modal dialog and two lists does not change anything in regards to how the store is used.
您正在使用模式对话框和两个列表的事实不会改变商店的使用方式。
This is likely out of scope for what you are trying to accomplish but something you could keep in mind. 对于您要完成的工作,这可能超出范围,但您需要牢记。
If you want to share a value between components, you should do a Service that will be injected in each component where you need it. 如果要在组件之间共享值,则应执行一项服务 ,该服务将注入到需要的每个组件中。
@Injectable({
providedIn: 'root',
})
export class ResultListService {
public myResultList: string;
}
(With the providedIn: 'root'
, it will be injected at the root of your app so it will be instancied only one time and the same instance will be shared among components) (使用
providedIn: 'root'
,它将注入到应用程序的根目录,因此只能实例化一次,并且在组件之间共享同一实例)
Then you pass it in the constructor parameters of your componenents: 然后,将其传递到组件的构造函数参数中:
export class SidebarComponent {
constructor(public resultListService: ResultListService){}
// this.resultListService.myResultList
}
Component A- HTML组件 A- HTML
<button (click) = "changeFoo()">Change Value</button>
Component A- Typpescript组件 A - 打字稿
import { SharedService } from './../../shared.service';
constructor(private sharedService: SharedService) {}
Component B-Html组件 B-Html
<div style="margin:0; padding:0">
{{xIsANumberVal == null? '' : "Value Passed From A Component
Comp(Parent): "+xIsANumberVal }}
</div>
Component B- Typescript组件 B- 打字稿
import { SharedService } from './../../shared.service';
xIsANumberVal!: number;
constructor(
private sharedService: SharedService
) {}
ngOnInit() {
this.receiveValueFromService();
}
receiveValueFromService() {
this.sharedService.valueSource.subscribe(value => {
this.xIsANumberVal = value;
});
}
Shared Service共享服务
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class SharedService {
xIsANumberVal: number = 5;
valueSource: Subject<number> = new Subject();
get abc(): Subject<number> {
return this.valueSource;
}
constructor() { }
changeFoo(xIsANumberVal: number) {
this.valueSource.next(xIsANumberVal);
}
}
Working Example: https://stackblitz.com/edit/github-u6xvad?file=src%2Fapp%2Fsecond%2Fsecond.component.ts工作示例: https : //stackblitz.com/edit/github-u6xvad?file=src%2Fapp%2Fsecond%2Fsecond.component.ts
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.