【问题标题】:Angular does not execute bindings, directive and ngOnInit when route changeAngular 在路由更改时不执行绑定、指令和 ngOnInit
【发布时间】:2017-11-14 13:58:36
【问题描述】:

在我的应用程序中,我遇到了 Angular 不绑定属性的问题。它也不会调用ngOnInitngAfterViewInit 或执行指令。
这是部分 LoginComponent 代码:

@Component({
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit

//.....

    public test: string = 'some dummy test';

    constructor(
        private cd: ChangeDetectorRef,
        private fb: FormBuilder, private router: Router, private route: ActivatedRoute,
        private authService: AuthService,
        private usersService: UserService,
        private notificationsService: NotificationsService
    )
    {
        this.loginForm = fb.group({
            email: ["", Validators.required],
            password: ["", Validators.required]
        });
        console.info("constructor");
    }

    ngOnInit()
    {
        console.info("ngOnInit");
        this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';        
    }

    ngAfterViewInit()
    {
        this.initGapi();
        console.info("afterviewinit");
    }

奇怪的是,这在我打开页面或 HMR 刷新页面时有效,但在我登录和注销时无效。
这是注销代码:

logout(): boolean
{
    this.authService.logout();
}

//authservice.ts
logout()
{    
    localStorage.removeItem("token");
    localStorage.removeItem("refresh_token");
    localStorage.removeItem("profile");

    if (gapi.auth2)
    {
        const instance = gapi.auth2.getAuthInstance();
        if (instance)
        {
            instance.signOut().then(() =>
            {
                this.router.navigate(["login"]);
            });
            return;
        }
    }
    this.router.navigate(["login"]);
}

我注销和绑定不发生的区别是:

  • 按钮没有样式。这应该做kendoButton指令<button class="center" kendoButton type="submit">

  • 缺少测试绑定(一些虚拟测试)

  • ngOnInitngAfterViewInit 未被调用。

控制台没有错误。我还记录屏幕(它从空白页开始)。我有最新的 Chrome 和 Firefox,两个浏览器都有同样的问题。

有人知道哪里出了问题或我还能尝试什么吗?

【问题讨论】:

  • 您的登录逻辑将用户重定向到哪里?
  • 可能相关 stackoverflow.com/a/47268066/3731501 ,但我不确定您的路由器插座发生了什么。
  • Danel:它从 localhost:50222/home 重定向到 localhost:50222/login。 estus:我不明白这与你提供的问题有什么关系。

标签: angular angular2-routing angular2-template


【解决方案1】:

如果 gapi 在 Angulars 区域之外运行,则不会通知更改检测运行。您可以在 Angulars 区域内显式运行代码,例如

constructor(private zone:NgZone) {}

...    

  this.zone.run(() => {
    this.router.navigate(["login"])
  });

【讨论】:

  • 我明白,我已经回答了我自己的问题。我觉得奇怪的是它不起作用。路由器更改路由,显示新页面。这一切都发生在 Angular 之外吗?
  • 如果 `instance.signOut().then(() => ... )` 在 Angulars 区域外调用 ...,则调用的所有内容都在 Angulars 区域外运行。添加组件的路由器在 Angulars 区域之外,因此不会检测到新组件及其子组件的更改。除非通过其他方式进行更改检测,否则不会发生任何事情。
  • 您没有在答案中使用zone,但这是应该在这里使用的。 ChangeDetectorRef.detectChanges() 仅适用于本地组件及其子组件。
【解决方案2】:

问题出在 Google gapi 库中:

const instance = gapi.auth2.getAuthInstance();
if (instance)
{
    instance.signOut().then(() =>
    {
        this.router.navigate(["login"]);    //This is runned outside Angular's context.
    });
    return;
}

instance.signOut 的回调在 Angular 的上下文之外运行。 解决办法是把导航放到google.gapi回调外:

const instance = gapi.auth2.getAuthInstance();
if (instance)
{
    instance.signOut();
    this.router.navigate(["login"]);
}

或者,如果您希望在从 Google 退出后导航,请使用区域。 This 可能会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 2012-07-24
    • 2018-02-02
    • 2019-02-24
    • 2014-05-05
    • 2018-03-30
    相关资源
    最近更新 更多