angular2 视图不更新从共享服务更改的数据
angular2 view not updating data changed from shared service
我正在尝试显示来自我的共享服务的数据,但它没有显示。任何人都可以帮助我,我从快几天开始构建这个。我已经尝试过 NgZone 和 ChangeDetectorRef,但对我不起作用。
home.component.html
<div *ngFor="let order of orders " class="order-cards">
<div class="order-card">
<div class="btn-order-card">
<button type="submit" class="btn btn-success " (click)="viewOrder(order)">View the Order </button>
</div>
</div>
</div>
home.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { SharedService } from '../services/shared.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor( private route: Router, private sharedService: SharedService) { }
ngOnInit() {
}
viewOrder(order) {
this.route.navigate(['../view-order'])
this.sharedService.viewOrderValues(order);
}
}
shared.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
Injectable()
export class SharedService {
constructor() { }
private viewOrderSource = new Subject<any>();
viewOrder$ = this.viewOrderSource.asObservable();
viewOrderValues(data: any) {
this.viewOrderSource.next(data);
return data;
}
}
查看-order.component.ts
import { Component, OnInit } from '@angular/core';
import { SharedService } from '../services/shared.service';
@Component({
selector: 'app-view-order',
template: '{{orderValues}}',
styleUrls: ['./view-order.component.scss']
})
export class ViewOrderComponent implements OnInit {
orderValues: any;
constructor(private sharedService: SharedService) {
}
ngOnInit() {
this.sharedService.viewOrder$.subscribe((data) => {
this.orderValues = data;
});
}
}
您必须将列表设置为数据的副本。除非您将数据重置为完全不同的对象或数组,否则 angular 不会意识到它已更改。
你可以对数组使用this.arrayName = this.arrayName.slice();
或者对于一个对象
var objName = Object.assign({}, objName)
努力做到
this.sharedService.viewOrderValues(order);
this.route.navigate(['../view-order'])
我觉得你先导航,所以它没有调用那个函数,因此你的观察者没有被调用。
home.component.html 引用变量 "orders"。 home.component.ts 中不存在此变量。当您的服务 returns 数据时,您可以将其保存为实例变量并在您的 html 中引用它。
编辑:
我相信您也可以直接绑定到服务中的可观察对象。
我认为你的做法是错误的。
你应该使用routing based Resolve
并将参数作为id传递给组件,这样你就可以在组件加载.[=25时获取数据=]
修改了您的 shared.service.ts
以支持基于 id 的搜索:
@Injectable()
export class SharedService {
private orders = []; // initialize or fetch from service, IDK
ordersChanged = new Subject<any[]>();
constructor() { }
addOrder(order: any) {
this.orders.push(order);
this.ordersChanged.next(this.getOrders());
}
getOrders(): any[] {
return this.orders.slice();
}
getOrder(id: number) {
// your logic to find order
return this.orders[id];
}
}
在你的 home.component.html
:
<div *ngFor="let order of orders; let i = index" class="order-cards">
<div class="order-card">
<div class="btn-order-card">
<button
type="submit"
class="btn btn-success"
(click)="viewOrder(i)">View the Order</button>
</div>
</div>
</div>
以及您的 home.component.ts
中的相应变化:
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnDestroy {
orders: string[];
subscription: Subscription;
constructor(private route: Router, private sharedService: SharedService) { }
ngOnInit() {
this.orders = this.sharedService.getOrders();
this.subscription = this.sharedService.ordersChanged.subscribe(orders => this.orders = orders);
}
viewOrder(index: number) {
this.route.navigate(['/view-order', index])
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
您可以创建一个 OrderResolver
服务:
@Injectable()
export class OrderResolver implements Resolve<any>{
constructor(private sharedService: SharedService) { }
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): string | Observable<string> | Promise<string> {
const id = +route.params['id'];
return this.sharedService.getOrder(id);
}
}
你可以很容易地在上面注入一个Router
并处理给定id没有订单的情况。
在您的路由模块 class 中,更改 view-order
路径以接受参数作为 id 并使用解析器在路由加载期间查找顺序:
{
path: 'view-order/:id',
component: ViewOrderComponent,
resolve: { order: OrderResolver }
}
然后在你的 ViewOrderComponent
:
export class ViewOrderComponent implements OnInit {
orderValues: any;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.orderValues = this.route.snapshot.data['order'];
}
}
改变
private viewOrderSource = new Subject<any>();
到
private viewOrderSource = new BehaviorSubject<Object>(null);
在shared-seriice.ts
我正在尝试显示来自我的共享服务的数据,但它没有显示。任何人都可以帮助我,我从快几天开始构建这个。我已经尝试过 NgZone 和 ChangeDetectorRef,但对我不起作用。
home.component.html
<div *ngFor="let order of orders " class="order-cards">
<div class="order-card">
<div class="btn-order-card">
<button type="submit" class="btn btn-success " (click)="viewOrder(order)">View the Order </button>
</div>
</div>
</div>
home.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { SharedService } from '../services/shared.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor( private route: Router, private sharedService: SharedService) { }
ngOnInit() {
}
viewOrder(order) {
this.route.navigate(['../view-order'])
this.sharedService.viewOrderValues(order);
}
}
shared.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
Injectable()
export class SharedService {
constructor() { }
private viewOrderSource = new Subject<any>();
viewOrder$ = this.viewOrderSource.asObservable();
viewOrderValues(data: any) {
this.viewOrderSource.next(data);
return data;
}
}
查看-order.component.ts
import { Component, OnInit } from '@angular/core';
import { SharedService } from '../services/shared.service';
@Component({
selector: 'app-view-order',
template: '{{orderValues}}',
styleUrls: ['./view-order.component.scss']
})
export class ViewOrderComponent implements OnInit {
orderValues: any;
constructor(private sharedService: SharedService) {
}
ngOnInit() {
this.sharedService.viewOrder$.subscribe((data) => {
this.orderValues = data;
});
}
}
您必须将列表设置为数据的副本。除非您将数据重置为完全不同的对象或数组,否则 angular 不会意识到它已更改。
你可以对数组使用this.arrayName = this.arrayName.slice(); 或者对于一个对象 var objName = Object.assign({}, objName)
努力做到
this.sharedService.viewOrderValues(order);
this.route.navigate(['../view-order'])
我觉得你先导航,所以它没有调用那个函数,因此你的观察者没有被调用。
home.component.html 引用变量 "orders"。 home.component.ts 中不存在此变量。当您的服务 returns 数据时,您可以将其保存为实例变量并在您的 html 中引用它。
编辑: 我相信您也可以直接绑定到服务中的可观察对象。
我认为你的做法是错误的。
你应该使用routing based Resolve
并将参数作为id传递给组件,这样你就可以在组件加载.[=25时获取数据=]
修改了您的 shared.service.ts
以支持基于 id 的搜索:
@Injectable()
export class SharedService {
private orders = []; // initialize or fetch from service, IDK
ordersChanged = new Subject<any[]>();
constructor() { }
addOrder(order: any) {
this.orders.push(order);
this.ordersChanged.next(this.getOrders());
}
getOrders(): any[] {
return this.orders.slice();
}
getOrder(id: number) {
// your logic to find order
return this.orders[id];
}
}
在你的 home.component.html
:
<div *ngFor="let order of orders; let i = index" class="order-cards">
<div class="order-card">
<div class="btn-order-card">
<button
type="submit"
class="btn btn-success"
(click)="viewOrder(i)">View the Order</button>
</div>
</div>
</div>
以及您的 home.component.ts
中的相应变化:
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnDestroy {
orders: string[];
subscription: Subscription;
constructor(private route: Router, private sharedService: SharedService) { }
ngOnInit() {
this.orders = this.sharedService.getOrders();
this.subscription = this.sharedService.ordersChanged.subscribe(orders => this.orders = orders);
}
viewOrder(index: number) {
this.route.navigate(['/view-order', index])
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
您可以创建一个 OrderResolver
服务:
@Injectable()
export class OrderResolver implements Resolve<any>{
constructor(private sharedService: SharedService) { }
resolve(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): string | Observable<string> | Promise<string> {
const id = +route.params['id'];
return this.sharedService.getOrder(id);
}
}
你可以很容易地在上面注入一个Router
并处理给定id没有订单的情况。
在您的路由模块 class 中,更改 view-order
路径以接受参数作为 id 并使用解析器在路由加载期间查找顺序:
{
path: 'view-order/:id',
component: ViewOrderComponent,
resolve: { order: OrderResolver }
}
然后在你的 ViewOrderComponent
:
export class ViewOrderComponent implements OnInit {
orderValues: any;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.orderValues = this.route.snapshot.data['order'];
}
}
改变
private viewOrderSource = new Subject<any>();
到
private viewOrderSource = new BehaviorSubject<Object>(null);
在shared-seriice.ts