简体   繁体   English

如何在Ember中刷新控制器属性?

[英]How to refresh a controller property in Ember?

I have been struggling with this for the past two days. 在过去的两天里,我一直在为此苦苦挣扎。 I can't find a way to refresh a controller property in Ember - in other words, make the handlebars template look up for the controller property again, other than caching the old value. 我找不到在Ember中刷新控制器属性的方法-换句话说,除了缓存旧值之外,使车把模板再次查找该控制器属性。 The problem has to do with sessionStorage. 问题与sessionStorage有关。 Here's the code: 这是代码:

<script type="text/x-handlebars" id="start">
    {{log isLoggedIn}}
    {{#if isLoggedIn}}
        <p>Welcome, <strong>{{controllers.application.name}}</strong>!<br/>
           Your user role is: <strong>{{controllers.application.role}}</strong></p>
    {{else}}
        <p>Unfortunately, you're not logged in so you cannot access this content.</p>
    {{/if}}
</script>

The application handlebars template has a link for log in. 应用程序把手模板具有用于登录的链接。

Here's a part of my app.js: 这是我的app.js的一部分:

App.ApplicationController = Ember.ObjectController.extend({    
    session: false,
    hasSession: function() {
        var session = window.sessionStorage.getItem("session");
        if (session) {
            this.set("session", true);
            return session.length === 16;
        }
        return false;
    }.property("session"),

App.StartController = Ember.ObjectController.extend({
    needs: ["application"],
    isLoggedIn: function() {
        return this.get("controllers.application.hasSession");
    }.property("controllers.application.hasSession")
});

App.LoginController = Ember.ObjectController.extend({
    username: "deus",
    password: "ha", //TODO: replace with null
    actions: {
        login: function() {
            logIn(this);
        }
    }
});

function logIn(self) {
    $.ajax({
        dataType: "json",
        url: "userValidation.json",
        async: false,
        success: function(data) {
            if (data.status.code === 200) {
                window.sessionStorage.setItem("session", data.users.session);
                window.sessionStorage.setItem("permissions", data.users.permissions);
                window.sessionStorage.setItem("username", data.users.username);
                window.sessionStorage.setItem("name", data.users.name);
            } else {
                alert("Unable to log in! Status code is " + data.status.code.toString());
            }
        }
    }).done(function() {
        //TODO: Move logic here?
    });
}

I've tried all I can think of. 我已经尽力了。 I see in my chrome developer's console that the session is set properly. 我在chrome开发人员的控制台中看到会话设置正确。 However, when I navigate to the start page, I get that "unfortunately" message. 但是,当我导航到start页面时,会收到“不幸”消息。 My console log says that session is false. 我的控制台日志显示该会话为false。

If I try this: 如果我尝试这样做:

App.ApplicationController = Ember.ObjectController.extend({
    hasSession: function() {
        return getLoggedIn();
    }
});

function getLoggedIn() {
    var session = window.sessionStorage.getItem("session");
    if (session) {
        return session.length === 16;
    }
    return false;
}

I still have the same (or rather similar) problem - navigating to the start page still shows the message as if the user is not logged in, even though sessionStorage has all the stuff. 我仍然有相同(或非常相似)的问题-导航到start页面仍然显示消息,如果用户没有登录,即使sessionStorage的拥有所有的东西。 But when I refresh the page manually, it gives me the proper "Welcome" message. 但是,当我手动刷新页面时,它会给我正确的“欢迎”消息。

How can I solve this problem? 我怎么解决这个问题? Basically, I need the controller to "understand" that the session has changed, and realize that the user has logged in - or, in other words, I need to refresh the controller's property (without reloading the page). 基本上,我需要控制器“了解”会话已更改,并意识到用户已登录-换句话说,我需要刷新控制器的属性(无需重新加载页面)。

Ember doesn't have any built in functionality for watching the session storage, but it really isn't necessary here. Ember没有用于监视会话存储的任何内置功能,但实际上在这里没有必要。 You can just do it in the resolved ajax call (something like this). 您可以在已解决的Ajax调用中执行此操作(类似这样)。

App.ApplicationController = Ember.ObjectController.extend({    
    session: '',
    hasSession: function() {
        return this.get('session.length') === 16;
    }.property("session"),

App.StartController = Ember.ObjectController.extend({
    needs: ["application"],
    isLoggedIn: Em.computed.alias("controllers.application.hasSession")
});

App.LoginController = Ember.ObjectController.extend({
    needs: ["application"],
    application: Em.computed.alias("controllers.application"),
    username: "deus",
    password: "ha", //TODO: replace with null
    actions: {
        login: function() {
            var self = this;
            logIn(this).done(function(result){
               var session = result.users.session; // or whatever this is
               self.set('application.session', session);
            });
        }
    }
});

function logIn(self) {
    return $.ajax({
        dataType: "json",
        url: "userValidation.json",
        async: false,
        success: function(data) {
            if (data.status.code === 200) {
                window.sessionStorage.setItem("session", data.users.session);
                window.sessionStorage.setItem("permissions", data.users.permissions);
                window.sessionStorage.setItem("username", data.users.username);
                window.sessionStorage.setItem("name", data.users.name);
            } else {
                alert("Unable to log in! Status code is " + data.status.code.toString());
            }
        }
    })
}

Computed Properties 计算属性

Ember's computed properties are cached by default and are lazily loaded. Ember的计算属性默认情况下被缓存并延迟加载。 This means that the only way a property is recalculated is if one of the dependent properties has changed. 这意味着,重新计算属性的唯一方法是是否更改了从属属性之一。 In the example below, if you were to change bar, foo would then be marked dirty, and then be recalculated (if being watched by someone); 在下面的示例中,如果要更改bar,则foo将被标记为脏,然后重新计算(如果有人监视);

bar:'asdf',
foo: function(){
  return this.get('bar');
}.property('bar')

In this example it would also only get recalculated if bar changed. 在此示例中,如果更改了bar,也只会重新计算。 Unfortunately if baz changed foo wouldn't be recalculated. 不幸的是,如果baz更改了,foo将不会被重新计算。

bar:'asdf',
baz:'fdas',
foo: function(){
  return this.get('bar') + this.get('baz');
}.property('bar')

Volatile computed properties 挥发性计算属性

Volatile computed properties will be recalculated every time they are requested. 每次请求时,都会重新计算易失的计算属性。

bar:1,
foo: function(){
   this.incrementProperty('bar');
   return this.get('bar');
}.property().volatile(),

blah: function(){
  this.get('foo');
  this.get('foo');
  this.get('foo');
}

Example: http://emberjs.jsbin.com/donalabu/1/edit 示例: http//emberjs.jsbin.com/donalabu/1/edit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM