将数组绑定到模板中的组件仅适用于页面加载
Binding an array to a component in template is working only on page load
我的布局模板中有一个组件(用于导航栏),我正在使用可注入服务,因此组件可以根据自己的逻辑更改导航栏的内容。
这是模板标记的一部分
默认-layout.component.html
<app-sidebar-nav [navItems]="defaultLayoutService.items$ | async" [perfectScrollbar] [disabled]="appSidebar.minimized"></app-sidebar-nav>
默认-layout.component.ts
constructor(public defaultLayoutService: DefaultLayoutService) {
}
默认布局-service.ts
import { navItems, ICustomNavData } from '../../_nav';
items$: Observable<ICustomNavData[]>;
navItems = <ICustomNavData[]>navItems; //cast to a custom interface I created.
setNavItemAttribute(itemKey: string, itemAttribute: string, text: string) {
let menuItem = this.navItems.find(r => r.key == itemKey);
if (menuItem && menuItem.hasOwnProperty(itemAttribute)) {
menuItem[itemAttribute] = text;
}
console.log(this.navItems); //this outputs the items and shows they were modified correctly
this.items$ = new Observable(ob => { ob.next(this.navItems); })
}
所以我的组件也可以访问 DefaultLayoutService
并使用不同的参数调用 setNavItemAttribute
。
有效,但仅在我刷新页面时有效。在单应用页面模式下浏览时,触发调用不同参数的setNavItemAttribute
,导航项保持不变。
我在这里正确处理了 Observable 吗?
Am I handling the Observable correctly here ?
我在这里看到 2 个潜在问题:
- 每次更新当前数组中的相应项时,您都将服务中的
items$
Observable 设置为一个新实例。
- 你将那个 Observable 的值设置为数组的同一个实例,所以 Angular 的变化检测不认为数组已经改变(即使 内的值 它有)。
让我们解决这些问题:
您可以使用中介 Subject
从您的服务中触发在 Observable
上发出的值,并在您想要更新值时对其调用 .next
。
您可以通过正常公开 Observable
来实现此目的,该 Observable
是从 Subject
构建的。这是为了防止外部影响能够 inadvertently/maliciously 直接在主题上调用 .next
。
看起来像这样:
export class DefaultLayoutService {
private _navItems: <ICustomNavData[]>;
private readonly _itemsSubject = new Subject<ICustomNavData[]>();
items$: Observable<ICustomNavData[]> = this._itemsSubject.asObservable();
setNavItemAttribute(itemKey: string, itemAttribute: string, text: string) {
// code to update corresponding item in navItems array
this._itemsSubject.next(this.navItems);
}
}
因为 Observable
来自 Subject
,它将发出您在服务方法中传递给主题的最新值。
请注意,当您首次初始化组件和数组时,您需要使用 _itemsSubject
的第一个值调用 .next
,因此它可以在 [=14] 上发射=].
When browsing in single app page mode, triggering a call to setNavItemAttribute with different parameters, the navigation items remain the same.
因为对数组 本身 的引用没有改变,所以 Angular 的变化检测不会使用数组中的新值重新呈现。似乎是人们偶然发现的常见问题。
我以前做过的一种方法是使用 ...
展开运算符创建一个“新”数组,使用旧数组。这样,引用就不同了,并触发更改检测以使用新值重新渲染。
像这样:
setNavItemAttribute(...) {
// code to update the corresponding item in the existing _navItems array
const navItemsCopy = [...this._navItems];
// use the new array reference to trigger change detection
this._itemsSubject.next(navItemsCopy);
}
还有很多方法可以做到这一点,因此请四处看看,看看哪种方法最适合您的情况并适合您。
我的布局模板中有一个组件(用于导航栏),我正在使用可注入服务,因此组件可以根据自己的逻辑更改导航栏的内容。
这是模板标记的一部分
默认-layout.component.html
<app-sidebar-nav [navItems]="defaultLayoutService.items$ | async" [perfectScrollbar] [disabled]="appSidebar.minimized"></app-sidebar-nav>
默认-layout.component.ts
constructor(public defaultLayoutService: DefaultLayoutService) {
}
默认布局-service.ts
import { navItems, ICustomNavData } from '../../_nav';
items$: Observable<ICustomNavData[]>;
navItems = <ICustomNavData[]>navItems; //cast to a custom interface I created.
setNavItemAttribute(itemKey: string, itemAttribute: string, text: string) {
let menuItem = this.navItems.find(r => r.key == itemKey);
if (menuItem && menuItem.hasOwnProperty(itemAttribute)) {
menuItem[itemAttribute] = text;
}
console.log(this.navItems); //this outputs the items and shows they were modified correctly
this.items$ = new Observable(ob => { ob.next(this.navItems); })
}
所以我的组件也可以访问 DefaultLayoutService
并使用不同的参数调用 setNavItemAttribute
。
有效,但仅在我刷新页面时有效。在单应用页面模式下浏览时,触发调用不同参数的setNavItemAttribute
,导航项保持不变。
我在这里正确处理了 Observable 吗?
Am I handling the Observable correctly here ?
我在这里看到 2 个潜在问题:
- 每次更新当前数组中的相应项时,您都将服务中的
items$
Observable 设置为一个新实例。 - 你将那个 Observable 的值设置为数组的同一个实例,所以 Angular 的变化检测不认为数组已经改变(即使 内的值 它有)。
让我们解决这些问题:
您可以使用中介 Subject
从您的服务中触发在 Observable
上发出的值,并在您想要更新值时对其调用 .next
。
您可以通过正常公开 Observable
来实现此目的,该 Observable
是从 Subject
构建的。这是为了防止外部影响能够 inadvertently/maliciously 直接在主题上调用 .next
。
看起来像这样:
export class DefaultLayoutService {
private _navItems: <ICustomNavData[]>;
private readonly _itemsSubject = new Subject<ICustomNavData[]>();
items$: Observable<ICustomNavData[]> = this._itemsSubject.asObservable();
setNavItemAttribute(itemKey: string, itemAttribute: string, text: string) {
// code to update corresponding item in navItems array
this._itemsSubject.next(this.navItems);
}
}
因为 Observable
来自 Subject
,它将发出您在服务方法中传递给主题的最新值。
请注意,当您首次初始化组件和数组时,您需要使用 _itemsSubject
的第一个值调用 .next
,因此它可以在 [=14] 上发射=].
When browsing in single app page mode, triggering a call to setNavItemAttribute with different parameters, the navigation items remain the same.
因为对数组 本身 的引用没有改变,所以 Angular 的变化检测不会使用数组中的新值重新呈现。似乎是人们偶然发现的常见问题。
我以前做过的一种方法是使用 ...
展开运算符创建一个“新”数组,使用旧数组。这样,引用就不同了,并触发更改检测以使用新值重新渲染。
像这样:
setNavItemAttribute(...) {
// code to update the corresponding item in the existing _navItems array
const navItemsCopy = [...this._navItems];
// use the new array reference to trigger change detection
this._itemsSubject.next(navItemsCopy);
}
还有很多方法可以做到这一点,因此请四处看看,看看哪种方法最适合您的情况并适合您。