Angular 5:从HTML调用方法

3
我不明白为什么它不能工作。
我在尝试通过从html中调用一个方法来显示登录/注销链接。在控制台中,我可以看到它返回“true”,但它从未将该链接更改为“Logout”。屏幕上始终显示“Login”。
<ul class="nav navbar-nav navbar-right">
    <li class="nav-item dropdown" [hidden]="!authenticated()">
        <a class="nav-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            <i class="fa fa-user" aria-hidden="true"></i> Welcome, {{user}}!
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
            <a class="nav-link dropdown-item" (click)="logout()">Logout</a>
        </div>
    </li>
    <li class="nav-item dropdown" [hidden]="authenticated()">
        <a routerLinkActive="active" routerLink="/login">Login</a>
    </li>
</ul>

component.ts

authenticated() {
    console.log(localStorage.getItem('authenticated'));
    if(localStorage.getItem('authenticated') === 'true') {
        console.log("YES");
        return true;
    } else {
        console.log("NO");
        return false;    
    }
}

点击登录链接之前 在这里输入图像描述

点击登录链接后 在这里输入图像描述

输入正确的用户名/密码后(在此处可以看到控制台返回 true) 在这里输入图像描述


尝试使用 *ngIf 指令代替 hidden 指令。如果你想要隐藏,可以返回 null 而不是 false - Roberto Zvjerković
但是如果您查看控制台日志,它满足条件并打印“YES”,这意味着它返回字符串。 - SK.
只需将[hidden]替换为您应该使用的*ngIf即可。 *ngIf ="!authenticated()" - Roberto Zvjerković
完全和你的例子一样。让我写一个答案。 - Roberto Zvjerković
你忘记加感叹号了吗? - Roberto Zvjerković
显示剩余3条评论
2个回答

2

首先,不应该使用*ngIf指令来调用函数,因为它会在每次变更检测时运行。这可能会导致性能开销。要么使用一个变量,要么将您的方法转换为getter属性,例如:

get authenticated(): boolean {
    return localStorage.getItem('authenticated') === true;
}

其次,使用*ngIf代替[hidden]:
<ul class="nav navbar-nav navbar-right">
    <li class="nav-item dropdown" *ngIf="authenticated">
        <a class="nav-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            <i class="fa fa-user" aria-hidden="true"></i> Welcome, {{user}}!
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
            <a class="nav-link dropdown-item" (click)="logout()">Logout</a>
        </div>
    </li>
    <li class="nav-item dropdown" *ngIf="!authenticated">
        <a routerLinkActive="active" routerLink="/login">Login</a>
    </li>
</ul>

2
我无法看到使用getter属性相比函数的性能优势。为什么这样做更好? - David Walschots
@david-walschots 或许这个链接会有所帮助:https://dev59.com/CKbja4cB1Zd3GeqPcTH6#46903095 - FAISAL
1
是的,我明白函数调用会有一定的开销(即使在函数不做太多事情时,这种开销可能非常小)。然而,getter属性实际上只是一个函数,这就是为什么我在问的原因。 - David Walschots

1

hidden 指令替换为 *ngIf 指令。

<ul class="nav navbar-nav navbar-right">
    <li class="nav-item dropdown" *ngIf="!authenticated()">
        <a class="nav-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            <i class="fa fa-user" aria-hidden="true"></i> Welcome, {{user}}!
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
            <a class="nav-link dropdown-item" (click)="logout()">Logout</a>
        </div>
    </li>
    <li class="nav-item dropdown" *ngIf="authenticated()">
        <a routerLinkActive="active" routerLink="/login">Login</a>
    </li>
</ul>

它们的功能基本相同,但是ng-if指令会从DOM中移除元素,而hidden属性只是隐藏它。

另一种解决方法是将您的方法更改为:

authenticated() {
    console.log(localStorage.getItem('authenticated'));
    if(localStorage.getItem('authenticated') === 'true') {
        console.log("YES");
        return true;
    } else {
        console.log("NO");
        return null;    
    }
}

我明白你的意思,但是在我做出那个改变之后,我既看不到登录也看不到注销。我认为还有其他问题... - SK.
现在还有其他问题,你肯定会看到其中一个。你能在StackBlitz上制作一个可行的示例吗? - Roberto Zvjerković
让我们在聊天中继续这个讨论 - Roberto Zvjerković
我很蠢。你和我的代码都没问题。但是我犯了一个错误。如果你看到我的代码,注销链接在下拉菜单中。这就是为什么它没有显示出来的原因... - SK.
哈哈。这种情况每个人都会遇到!但是要学会使用 *ngIf(以及 @Faisal 提到的内容),这样时间就不会浪费了! - Roberto Zvjerković
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接