【问题标题】:Aurelia - Navmenu not updating based on @computed valueAurelia - 导航菜单未根据@computed 值更新
【发布时间】:2018-04-18 02:46:55
【问题描述】:

我从THIS 收到并回答了我认为正确的问题,但是我没有得到传播回视图的值。我已经添加了一些 console.logs 并且它们没有被击中。

这是我的 navMenu - 如果“loggedIn”在本地存储中具有值,我希望它为真...

        <template bindable="router">
        <require from="./navmenu.css"></require>
        <div class="main-nav">
            <div class="navbar navbar-inverse">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="#/home">Jobsledger.API</a>
                </div>
                <div class="navbar-collapse collapse">

                    <ul class="nav navbar-nav">

                        <li repeat.for="row of router.navigation" class="${ row.isActive ? 'link-active' : '' }">
                            <a href.bind="row.href" if.bind="loggedIn">${ row.title }</a>

                            <a href.bind="row.href" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"
                               if.bind="loggedIn">
                                ${row.title}
                                <span class="caret"></span>
                            </a>

                            <ul if.bind="loggedIn" class="dropdown-menu">
                                <li repeat.for="menu of row.settings.nav">
                                    <a href.bind="menu.href">${menu.title}</a>
                                </li>
                            </ul>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
        test ${loggedIn}
    </template>

这是显示@computedFrom 和getter 的navmenu.ts 视图模型:

            import { autoinject, inject, NewInstance } from "aurelia-framework";
        import { computedFrom } from "aurelia-binding";
        import { bindable } from "aurelia-templating";

        import { LoggedInService } from "../components/auth/LoggedInService";

        @autoinject
        export class Navmenu {
            constructor(private testAuthentication: LoggedInService) {
                console.log("loggedin value: ", this.testAuthentication.isAuthenticated())
            }

            @computedFrom('testAuthentication.authenticated')
            get loggedIn() {
                console.log("loggedin value: ", this.testAuthentication.isAuthenticated())
                return this.testAuthentication.isAuthenticated()
            }
        }

这是我的登录类 - 非常简单 - 关闭并在本地存储中获取一个值 - 如果它不存在则返回 false。

         export class LoggedInService {
          private LOGGED_IN = "loggedIn";
          constructor() {}

          isAuthenticated(): boolean {
            var authenticated = localStorage.getItem(this.LOGGED_IN);

            console.log("LOGGEDIN - typeof: ", authenticated);

            if (authenticated != null) {
              return true;
            } else return false;
          }
        }

我的 console.logs 都没有显示在控制台中,这意味着这些功能都没有被击中..我不知道为什么..应该很简单..

有人可以看看这个并指导我为什么它仍然不起作用?

更新

感谢 Jeremy 看一看,我已经尝试实施了这一点。这是我更新的课程。

我已经更改了课程的名称,但它们代表了 Jeremy 的建议。在这里,它们的顺序与他呈现它们的顺序相同......

这是我的“user.ts”版本:

        export class LoggedInService {
        private LOGGED_IN = "loggedIn";

        isLoggedIn: boolean = false;
        userName: string = 'anonymous';

        constructor() { }

        isAuthenticated(): boolean {
            var authenticated = localStorage.getItem(this.LOGGED_IN);

            console.log("LOGGEDIN value HERE!: ", authenticated);

            if (authenticated != null) {
                return true;
            } else {
                return false;
            }
        }
    }

我将“isLoggedIn”设置为“假”,“用户名”设置为“匿名”。

这是我的“navmenu.ts”版本:

    import { autoinject } from "aurelia-framework";
    import { bindable } from "aurelia-templating";
    import { LoggedInService } from "../components/auth/LoggedInService";

    @autoinject
    export class Navmenu {

        constructor(public loggedInService: LoggedInService) { }
    }

我认为这应该让我的 navmenu.html - 视图 - 访问这些值,在这里我不确定应该如何在 if.bind 中访问它们。我只是想使用以下方法对其进行测试:

 <div if.bind="loggedInService.isLoggedIn">
        working
    </div>

这没用。

最后是我的 auth_service.ts 版本。这是进行提取以登录的地方 - 我在提取中设置了loggedIn和用户名的值:

    constructor(
    private login: userLogin,
    private loggedinService: LoggedInService,
    private tokenService: TokenService,
    private userService: UserService,
    private router: Router,
    private http: HttpClient,
    private controllerFactory: ValidationControllerFactory
) {
    this.router = router;
    this.controller = controllerFactory.createForCurrentScope();
    this.controller.addRenderer(new BootstrapFormRenderer());


    // Check if user is logged in
    if (this.loggedinService.isAuthenticated()) {
        loggedinService.isLoggedIn = true;
        loggedinService.userName = this.userService.getUserName();
    }
}

submitLogin() {
    if (this.controller.validate()) {
        // Lets do a fetch!

        this.login.Username = this.username;
        this.login.Password = this.password;

        const task = fetch("/api/jwt", {
            method: "POST",
            body: JSON.stringify(this.login),
            headers: new Headers({ 'content-type': 'application/json' })
        })
            .then(response => response.json())
            .then(data => {
                // First save the JWT and as well save it to loggedInService.
                this.loggedinService.isLoggedIn = this.tokenService.saveJWT(data);

                // Next go back to the api and get the username and save that to loggedInService also.
                this.loggedinService.userName = this.userService.saveUserName();

                // Finally redirect to home page.
                this.router.navigate("home");
            })
            .catch(error => {
                this.tokenService.clearJWT();
            });
    }
}

我仍然没有在导航菜单视图中获得任何类型的活动..不确定我是否已设置好想知道是否有人可以再看一下..也许我没有在导航栏视图中正确引用它。我注意到loggedInService 是navmenu 和login.ts 视图模型中的依赖项。这不应该工作还是搞砸了……

【问题讨论】:

  • 不应该从属性中计算出 isAuthenticated 吗? Authenticated 似乎是 isAuthenticated 函数中的局部变量
  • 想知道您是否可以对此进行扩展。我已将 @computedFrom('testAuthentication.authenticated') 更改为 @computedFrom('testAuthentication.isAuthenticated') 并且没有 consol.logs 出现..
  • 因为你目前已经构建了这个,所以没有办法让 Aurelia 不必对它进行脏检查。 computedFrom 在这里不起作用,因为您告诉它查看函数的结果(没有参数的函数),而不是简单的属性。如果您想避免脏检查,则需要彻底重新考虑如何检查用户是否登录。
  • 我正处于一个相当陡峭的学习曲线的开始阶段。. Ashley 表示我目前的方法存在缺陷... 很高兴重新考虑这一点.. 有人可以建议如何 1) 避免脏签入此实例和 2)根据本地存储变量更改的更改更新视图中的值。

标签: typescript data-binding dependency-injection aurelia


【解决方案1】:

这可能是因为您根本没有使用您的视图模型。尝试检查您是否引用了模块导航菜单视图模型,或其视图navmenu.html

【讨论】:

    【解决方案2】:

    您可以对此进行稍微不同的建模,并避免所有脏检查和computedFrom 的东西。

    为当前用户创建模型:

    user.ts

    export class User {
      isLoggedIn = false;
      name = 'anonymous';
    }
    

    然后在需要访问isLoggedIn 状态或用户详细信息的视图模型中依赖用户:

    navmenu.ts

    @autoinject
    export class Navmenu {
      constructor(public user: User) { }
    }
    

    进行登录工作或本地存储工作的服务也依赖于当前用户,当登录状态改变时更新其属性。

    auth-service.ts

    @autoinject
    export class AuthService {
      constructor(private user: User) { 
         if (... check local storage, etc ... ) {
           user.isLoggedIn = true;
           user.name = ....
         }
      }
    
      login(username, password) {
        return fetch('/api/login', { method: 'POST', body: { ... } })
          .then(result => {
             ... 
             ...
             this.user.isLoggedIn = true;
             this.user.name = username;
             ...
          });
      }
    }
    

    【讨论】:

    • 感谢 Jeremy 的观看。我已更新问题以反映您的解决方案。我仍然无法在导航菜单视图中访问这些变量...
    • 我遇到了第二个问题,因为我使用的 aurelia 模板具有自定义元素,并且将导航菜单作为没有视图模型的 html 视图导入。因此,即使我有正确的依赖关系,我也无法让任何绑定工作。用这个问题stackoverflow.com/a/47152839/5750758问了好几个问题,终于把绑定的问题搞定了。
    猜你喜欢
    • 2019-09-10
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    相关资源
    最近更新 更多