【问题标题】:In Emberjs - defining the model to implement authentication在 Emberjs - 定义模型以实现身份验证
【发布时间】:2014-03-05 20:49:32
【问题描述】:

我已经尝试了解 Emberjs 有一段时间了,我已经完成了“入门”链接上的“待办事项”应用程序,我已经阅读了所有文档,并且我已经从“Ember in行动”的书。

现在我正在尝试自己做一些事情,结果发现我遇到了各种各样的问题,所以我将从这篇文章的第一个开始。

我想出了以下模板:

<body>
    <script type="text/x-handlebars" data-template-name="user-navigation">
        <ul id="userNavigation">
            {{#if isAuthenticated}}
                <li>Welcome {{userName}}</li>
                <li>{{#link-to "awesome.index"}}logout{{/link-to}}</li>
                <li><a href="#">Settings</a></li>                   
            {{else}}
                <li>{{#link-to "awesome.login"}}login{{/link-to}}</li>
                <li><a href="#">sign up</a></li>
            {{/if}}
        </ul>
    </script>       

    <script type="text/x-handlebars" data-template-name="awesome/index">
        {{#if isAuthenticated}}
            <section id="userWidgets">
                <div>
                    <button id="createNewWidget">Create New Widget</button>
                </div>
                <div>
                    <ul>
                        {{#each widget}}
                            <li><a href="#">{{widgetName}}</a></li>
                        {{/each}}
                    </ul>
                </div>
            </section>
            <section id="selectedWidget">
            </section>          
        {{else}}
            <div id="welcome">Welcome to my awesome Site. You should sing up!</div>
        {{/if}}
    </script>

    <script type="text/x-handlebars" data-template-name="awesome/login">
        <ul id="mainLoginOptions">
            <li><button class="link-button" {{action 'facebookLogin'}}>Login with Facebook</button></li>
        </ul>
    </script>

    <script type="text/x-handlebars" id="application">
        <header id="siteHeader">
            <div id="logo" class="index-logo">My awesome SPA</div>
            <div id="userData" class="index-userdata">
                {{render "user-navigation" user}}
            </div>
        </header>
        <section id="mainContent">              
            {{outlet}}
        </section>
        <footer id="footer" class="index-footer"><div class="index-footer-content">Copyright 2014</div></footer>
    </script>
</body>

基本上它是顶部的标题,带有“登录/注册”或“注销/设置”链接,具体取决于用户是否登录。并在主要内容部分显示“欢迎”消息或登录用户的内容。

我正在尝试弄清楚如何处理登录工作流,以便标题模板正确呈现,并且主要内容与用户数据一起呈现。我在看this link to get ideas,但我仍然有很多关于如何实现它的问题。

我的 JavaScript 代码如下所示:

window.Awesome = Ember.Application.create({
    LOG_TRANSITIONS: true
});

Awesome.Router.map(function() {
    this.resource("awesome", {path: "/"}, function(){
        this.route('login');
    });
});

Awesome.AwesomeLoginRoute = Ember.Route.extend({
    actions:{
        facebookLogin: function(){
            var router = this;

            Awesome.User = Ember.Object.create({
                id: "1",
                isAuthenticated: "true",
                userName: "Serge"           
            });

            router.transitionTo('awesome.index');
        }
    }
});

不多,但基于该链接,我正在设置一个直接在应用程序中定义的“用户”对象,但我不知道如何将其发送到模板,以便他们使用它来正确呈现自己。

当然,我的想法是在某个时候我将使用一项服务从不同的社交网络获取令牌,但第一步是了解 Ember 的工作原理,为此我试图对对象进行存根。

非常感谢任何指针。

【问题讨论】:

    标签: javascript ember.js


    【解决方案1】:

    你有两个我能想到的选择。

    第一个选项是直接在模板中使用User 对象。 Ember.js 中的 Handlebars 模板将大写的变量名称解释为全局变量。因此,在您的模板中,您应该能够执行以下操作:

    {{#if Awesome.User.isAuthenticated}}{{/if}}
    

    选项二是将该对象用作要在其中使用数据的路由的模型。例如:

    Awesome.AwesomeIndexRoute = Ember.Route.extend({
        model: function() {
            return Awesome.User;
        }
    });
    

    现在awesome/index 模板的上下文是您的用户对象,因此您上面的代码应该可以工作。

    {{#if isAuthenticated}}{{/if}}
    

    前一种方法对初学者来说更容易一些,所以我现在推荐它。当您开始更多地了解 Ember.js 时,您会看到一些更好的模式,但只是小步骤,对吧? :)

    另外,您将isAuthenticated 属性设置为"true"(字符串值)。您可能应该使用布尔值。 "true" 将按照您的预期工作,但 "false" 在 Javascript 中是 truthy 值(所有非空字符串都是),因此您的 else 案例将永远不会被执行。

    【讨论】:

    • 感谢您的回答,但不幸的是,这些选项似乎都不起作用。当我尝试从 AwesomeIndexRoute 返回模型时,我尝试调用 {{render "user-navigation" user}} 和 {{render "user-navigation" model}},但都不起作用。仅我在帖子中包含的内容没有任何其他代码在起作用。我可能做错了什么?
    • former 对我来说似乎没问题。后者在使用渲染助手之类的东西时会有点麻烦,这就是我建议前者的原因。
    • 发生了一些奇怪的事情。通过尝试几件事,我最终只在“AWESOME/INDEX”模板上使用了第一个选项,它可以工作,但是如果我在“_user-navigation”部分以完全相同的方式完全限定对象,那么它们都不起作用。如果我再次尝试第二个选项,则只检查“AWESOME/INDEX”模板并再次删除部分中的条件,但只要我重新添加条件,它就会停止工作。
    • 我不确定那里发生了什么。你能在 JSBin 中重现这个问题吗?
    【解决方案2】:

    事实证明,要完成这项工作,必须发生很多事情。

    为了找到我采取的答案:

    • GJK 的回答。
    • 来自this post 的已接受答案的链接。
    • This blog 也在使用 Ember 进行身份验证。

    将所有内容放在一起后,我想出了以下内容:

    模板略有变化:

    <body>
            <script type="text/x-handlebars" data-template-name="_user-navigation">
                <ul id="userNavigation">
                    {{#if Awesome.authToken}}
                        <li>Welcome {{Awesome.User.userName}}</li>
                        <li><button class="link-button" {{action 'logout'}}>logout</button></li>                    
                        <li><a href="#">Settings</a></li>                   
                    {{else}}
                        <li>{{#link-to "awesome.login"}}login{{/link-to}}</li>
                        <li><a href="#">sign up</a></li>
                    {{/if}}
                </ul>
            </script>       
    
            <script type="text/x-handlebars" data-template-name="awesome/index">
                <div id="welcome">Welcome to my awesome Site. You should sing up!</div>
            </script>
    
            <script type="text/x-handlebars" data-template-name="awesome/login">
                <ul id="mainLoginOptions">
                    <li><button class="link-button" {{action 'facebookLogin'}}>Login with Facebook</button></li>
                </ul>
            </script>
    
            <script type="text/x-handlebars" data-template-name="widgets">
                <section id="userWidgets">
                    <div>
                        <button id="createNewWidget">Create New Widget</button>
                    </div>
                    <div>
                        <ul>
                            {{#each Awesome.User.widgets}}
                                <li><a href="#">{{widgetName}}</a></li>
                            {{/each}}
                        </ul>
                    </div>
                </section>
                <section id="selectedWidget">
                </section>                  
            </script>
    
            <script type="text/x-handlebars" id="application">
                <header id="siteHeader">
                    <div id="logo" class="index-logo">My awesome SPA</div>
                    <div id="userData" class="index-userdata">
                        {{partial "user-navigation"}}
                    </div>
                </header>
                <section id="mainContent">              
                    {{outlet}}
                </section>
                <footer id="footer" class="index-footer"><div class="index-footer-content">Copyright 2014</div></footer>
            </script>
        </body>
    

    而 JavaScript 代码变成了这样(注意应用中 localStorage 和全局变量的使用):

    window.Awesome = Ember.Application.create({
        LOG_TRANSITIONS: true,
        authToken: localStorage['authToken']
    });
    
    Awesome.ApplicationRoute = Ember.Route.extend({
        actions:{
            logout: function(){
                var router = this;
    
                Awesome.set('authToken', null);
                delete localStorage['authToken'];
                router.transitionTo('awesome.index');
            }
        }
    });
    
    Awesome.Router.map(function() {
        this.resource("awesome", {path: "/"}, function(){
            this.route('login');
        });
        this.resource("widgets");
    });
    
    Awesome.AwesomeLoginRoute = Ember.Route.extend({
        actions:{
            facebookLogin: function(){
                var router = this;
    
                //First call a service that authenticates the user and returns the token.
                Awesome.set('authToken', '123456789');
    
                //Then add the logic which will get the user's data. Most likely it should be a transition to another route.
                Awesome.User = Ember.Object.create({
                    id: "1",
                    userName: "Serge",
                    widgets: [{widgetName: "Great Widget"},{widgetName: "Fantastic Widget"},{widgetName: "Brutal Widget"}]
                });
    
                router.transitionTo('widgets');
            }
        }
    });
    

    这个练习仍然需要大量工作,但至少身份验证部分开始看起来不错,希望这对其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-09
      • 2018-04-09
      • 2011-04-24
      • 2016-07-24
      • 1970-01-01
      • 2017-07-17
      • 1970-01-01
      相关资源
      最近更新 更多