如何在jQuery Promise解析后调用Angular方法?Angular5集成MarvinJS报错求助
解决Angular5中MarvinJS Promise解析后调用Angular方法的问题
我之前也碰到过类似第三方库Promise和Angular上下文冲突的问题,大概率是**this的上下文丢失或者Angular变更检测未触发**导致的,给你几个具体的解决方案:
1. 修复this上下文问题
最常见的报错原因是MarvinJS的Promise回调里的this指向的不是你的Angular组件实例,所以调用this.sharedService时会找不到该服务。解决方法有两种:
方法A:使用箭头函数
箭头函数会继承外层作用域的this(也就是你的组件实例),这样就能正确访问sharedService了:
import { Component, OnInit } from '@angular/core'; import { SharedService } from './path-to-shared-service'; @Component({ selector: 'app-your-component', templateUrl: './your-component.component.html' }) export class YourComponent implements OnInit { constructor(private sharedService: SharedService) {} ngOnInit(): void { // MarvinJS的Promise调用示例 MarvinJSUtil.getEditor("#sketch").then((editor) => { // 这里的this就是组件实例,可正常调用服务方法 this.sharedService.openMarvinModal(false); }).catch((err) => { console.error("MarvinJS初始化失败:", err); }); } }
方法B:提前保存组件的this到变量
如果习惯用普通function回调,可以先把组件的this存到一个变量(比如self)里,再在回调中用这个变量访问服务:
ngOnInit(): void { const self = this; // 保存组件的this MarvinJSUtil.getEditor("#sketch").then(function(editor) { self.sharedService.openMarvinModal(false); // 用self代替this }).catch(function(err) { console.error("MarvinJS初始化失败:", err); }); }
2. 处理Angular变更检测问题
如果调用openMarvinModal后视图没有预期更新(比如模态框没显示),那是因为第三方库的Promise不在Angular的变更检测zone里,Angular不会自动触发视图更新。这时候可以用两种方式解决:
方法A:手动触发变更检测
注入ChangeDetectorRef,调用detectChanges()方法手动通知Angular更新视图:
import { Component, OnInit, ChangeDetectorRef } from '@angular/core'; import { SharedService } from './path-to-shared-service'; @Component({ selector: 'app-your-component', templateUrl: './your-component.component.html' }) export class YourComponent implements OnInit { constructor( private sharedService: SharedService, private cdr: ChangeDetectorRef // 注入变更检测服务 ) {} ngOnInit(): void { MarvinJSUtil.getEditor("#sketch").then((editor) => { this.sharedService.openMarvinModal(false); this.cdr.detectChanges(); // 手动触发变更检测 }); } }
方法B:用NgZone将代码包裹到Angular的zone中
注入NgZone,把调用服务的代码放到ngZone.run()里,Angular会自动处理变更检测:
import { Component, OnInit, NgZone } from '@angular/core'; import { SharedService } from './path-to-shared-service'; @Component({ selector: 'app-your-component', templateUrl: './your-component.component.html' }) export class YourComponent implements OnInit { constructor( private sharedService: SharedService, private ngZone: NgZone // 注入NgZone ) {} ngOnInit(): void { MarvinJSUtil.getEditor("#sketch").then((editor) => { this.ngZone.run(() => { this.sharedService.openMarvinModal(false); }); }); } }
先试试第一种修复上下文的方法,大部分情况下这个就能解决报错问题;如果遇到视图不更新的情况,再加上变更检测的处理就行。
内容的提问来源于stack exchange,提问作者Krishna
相关产品推荐
相关产品推荐

