如何确保 Ember 在重新加载时保存变量状态

How to ensure Ember is saving variable state on reload

我正在使用 Ember 创建和保存表单,但是当我重新加载页面时,跟踪表单是否已提交的开关重置为 false。

我有一个默认文本为 'You have no account linked' 的页面。然后我有一个按钮,当按下该按钮时会显示一个表单供用户填写信息。当他们点击提交并保存他们的信息时,表单消失并呈现一些关于他们帐户的文本。但是,当我重新加载页面时,文本呈现为默认 'You have no account linked',当我单击提交表单按钮时,它们的信息将填充到表单字段中。如何确保在重新加载页面时显示有关用户帐户的文本?

这是页面的控制器

export default Controller.extend({
  isToggled: false,
  emailConnected: false,
  actions: {
    submitImap(mailbox, toggle, email) {
      this.get('ajax').request(`/api/accounts/${this.session.account.id}/mailboxes/imap`, {
        method: 'POST',
        data: mailbox
      })
        .then(() => Utils.notify("IMAP settings saved.", 'success'))
        .catch(() => Utils.notify("Error saving IMAP account. Try again", 'error'));
      this.send('contract', toggle);
      this.send('expand', email);
    },
    disconnectIMAP(mailbox, property, email) {
      this.get('ajax').request(`/api/accounts/${this.session.account.id}/mailboxes/imap`, {
        method: 'DELETE',
        data: {
          user_id: mailbox.user_id
        }
      }).then(() => {
        this.set(property, { smtp: {}});
      })
        .then(() => Utils.notify("IMAP removed. ", 'success'))
        .catch(() => Utils.notify("Error removing IMAP account", 'error'));
      this.send('contract',email );
    },
    expand: function(toggle) {
      this.set(toggle, true)
    },
    contract: function(toggle) {
      this.set(toggle, false)
    }
  }
});

这是处理表单提交的模板

<h3>IMAP/SMTP</h3>
{{#if emailConnected}}

  {{#if isToggled}}
    <p> Edit your IMAP settings below </p>
  {{else}}
    <p>
      You currently have IMAP account <strong>{{imapMailbox.username}}</strong>
      connected for messaging.
    </p>
    <button  {{action "disconnectIMAP" imapMailbox 'imapMailbox' 'emailConnected' }} class = 'btn btn-danger'>Disconnect</button>
  {{/if}}

{{else}}
  <p>
    You currently do not have an account linked for messaging.
  </p>
{{/if}}

{{#if isToggled}}

  <form name='imap' class='modern-form full-width' {{action 'submitImap' imapMailbox 'isToggled' 'emailConnected' on="submit" }}>
    <div class='row'>
      <div class='col-sm-6'>
        <h4>IMAP</h4>
        <div class='form-group'>
          <label>
            Host
          </label>
          {{input type='text' required=true name='address' value=imapMailbox.address class='form-control'}}
        </div>
        <div class='form-group'>
          <label>
            Port
          </label>
          {{input type='text' required=true name='port' value=imapMailbox.port class='form-control'}}
        </div>
        <div class='form-check'>
          {{input type='checkbox' name='ssl' checked=imapMailbox.ssl class='form-check-input'}}
          <label for='ssl'>
            SSL
          </label>
        </div>
        <div class='form-check'>
          {{input type='checkbox' name='starttls' checked=imapMailbox.starttls class='form-check-input'}}
          <label>
            TLS
          </label>
        </div>
        <div class='form-group'>
          <label>
            Username
          </label>
          {{input type='text' required=true name='username' value=imapMailbox.username class='form-control'}}
        </div>
        <div class='form-group'>
          <label>
            Password
          </label>
          {{input type='password' required=true name='password' value=imapMailbox.password class='form-control'}}
        </div>
      </div>
      <div class='col-sm-6'>
        <h4>SMTP</h4>
        <div class='form-group'>
          <label>
            Host
          </label>
          {{input type='text' required=true name='smtp_address' value=imapMailbox.smtp.address class='form-control'}}
        </div>
        <div class='form-group'>
          <label>
            Port
          </label>
          {{input type='text' required=true name='smtp_port' value=imapMailbox.smtp.port class='form-control'}}
        </div>
        <div class='form-check'>
          {{input type='checkbox' name='smtp_ssl' checked=imapMailbox.smtp.ssl class='form-check-input'}}
          <label for='ssl'>
            SSL
          </label>
        </div>
        <div class='form-check'>
          {{input type='checkbox' name='smtp_starttls' checked=imapMailbox.smtp.enable_starttls_auto class='form-check-input'}}
          <label>
            TLS
          </label>
        </div>
        <div class='form-group'>
          <label>
            Username
          </label>
          {{input type='text' required='true' name='smtp_username' value=imapMailbox.smtp.user_name class='form-control'}}
        </div>
        <div class='form-group'>
          <label>
            Password
          </label>
          {{input type='password' required='true' name='smtp_password' value=imapMailbox.smtp.password class='form-control'}}
        </div>
      </div>
    </div>
    <button type="submit" class='btn btn-success'>
      Save
    </button>
    <button {{action 'contract' 'isToggled'}} class = 'btn btn-danger'>
      Cancel
    </button>
  </form>

{{else}}
  <button {{action 'expand' 'isToggled'}} class= 'btn btn-success'>
    Connect email
  </button>
{{/if}}

现在,如果我提交表单,行为符合预期,显示帐户的当前用户名,但在重新加载时,emailConnected 变量重置为 false,默认值 'you have no account connected' 存在,当我单击填充值的表单。

如果您 reload 页面(或)switch 到不同的路线,控制器的 属性 isToggled 将重置为其初始状态(即)到 false 你的情况。

如果您想在应用程序的各个部分保持状态并使用 属性 isToggled,您可以使用 ember service

但在您的情况下,您希望即使在页面 reloads 之后也保持 属性 状态。 ember 服务不会在页面重新加载后保持状态。

浏览器的使用来了localStorage

所以,在你的情况下 -

1) 在浏览器中存储 属性 isToggled 的值 localStorage

import { computed } from '@ember/object';

export default Controller.extend({
  isToggled: computed(function () {
    // when the user visits the page for the very first time,
    // isToggled value is set to false,
    // from next time it gets the value from browsers localStorage.
    if (localStorage.isToggled) {
      return JSON.parse(localStorage.isToggled);
     } else {
      return false;
    }
  }),
  ...
  actions: {
  ...
    expand: function() {
      localStorage.setItem('isToggled', JSON.stringify(true));
      this.set('isToggled', true);
    },
    contract: function() {
      localStorage.setItem('isToggled', JSON.stringify(false));
      this.set('isToggled', false);
    }
  ...
  }
});

现在,当页面重新加载时,isToggled 属性 状态不会更改为初始状态。

您可以在浏览器开发者工具中找到 isToggle 浏览器 localStorage 变量:Application -> Local Storage 选项卡

您也可以使用 Ember 本地存储库来实现此目的:https://github.com/funkensturm/ember-local-storage