【问题标题】:How to call a function from a template exactly once?如何从模板中调用一次函数?
【发布时间】:2016-08-15 12:28:59
【问题描述】:

我在 angular2 模板中使用函数调用。该函数本身使用 http.get() 执行一个 http 网络请求,并返回一个任何 [] 的 Observable,它实际上是一个 css 样式对象:

@Component({
    selector: "test-component",
    template: `<div *ngFor="let item of items" [ngStyle]="lookupStyle(item)"; }} </div>",
})
@Injectable()
export class TestComponent {

    @Input()
    items: Array<any>; 

    lookupStyle(params: any): Observable<any> {
        return this.http.get(/* ... */).map(/* ... */);
    }

    constructor(private http: Http) {}
}

但是上面的代码会触发无限循环!每次发生 angular2 变化检测时,都会评估函数 lookupStyle。由于http.get() 将触发更改检测运行,函数lookupStyle 在http 请求完成后重新评估 - 存在无限循环。

是否有解决方案或更好的方法让我可以告诉 angular 只评估函数 lookupStyle 一次?现在,我知道我可能会在我的视图模型上想出一些 .zip/.combineLatest 魔法,但这似乎有点过头了,并且会产生很多额外的代码——这就是我寻找更好方法的原因。

【问题讨论】:

  • 有什么阻止您将get 方法分解为单独的服务文件吗?
  • @Scrambo:我把它放到了组件中以保持示例简单;如果您将http.get 放入服务文件中,您将遇到同样的问题 - 它是问题的更改检测触发器(请记住,这不是像角度 1 中的脏检查)
  • 为什么不直接从 ngOnInit() 调用 http,而不是从 UI 调用?
  • 是的,这将是我所知道的 .zip/.combineLatest 方法。希望有一个更清洁的解决方案
  • 如果您使用 OnPush ChangeDetectionStrategy,则只有在数组中添加了新项目时才能运行更改检测。

标签: ajax angular typescript rxjs5 angular2-changedetection


【解决方案1】:

如果你真的只希望它运行一次,那么这应该可以解决问题:

hasBeenRun: boolean = false;
@Component({
    selector: "test-component",
    template: `<div *ngFor="let item of items" [ngStyle]="lookupStyle(item)"; }} </div>",
})
@Injectable()
export class TestComponent {

    @Input()
        items: Array<any>; 

        lookupStyle(params: any): Observable<any> {
            if(!this.hasBeenRun){
                this.hasBeenRun = true;
                return this.http.get(/* ... */).map(/* ... */);
            }
        }
}
constructor(private http: Http) {}

hasBeenRun 如果您希望再次调用它,则需要在其他地方将其设置回 false。希望这是您正在寻找的,尽管我也支持 ngOnInit() 是一个非常可行的解决方案。

【讨论】:

  • 这是不行的,因为在模板中我在*ngFor 环境中使用该功能。您的解决方案仅适用于第一次迭代,而不适用于所有元素。 (顺便说一句。每个人都可以想出这个解决方法——但这不是一个真正的解决方案)
  • 通过避免ngOnInit,您正在寻找一种解决方法:P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 2014-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-07
相关资源
最近更新 更多