2

ember.js アプリケーションでトップ ナビゲーション バーを作成し、それをコンポーネントに変換して、ユーザーがサインインしたときに簡単な「ようこそ {{currentUser.fullName}}」の紹介を表示できるようにしました。ナビゲーション バーがコンポーネントになる予定ですが、今のところ、これが正しく機能するようにしようとしていることです。また、ember-simple-auth アドオンも使用しており、session.isAuthenticatedこれを実現するために値を使用しています。

もちろん、ユーザーがサインインすると「インデックス」に移行する「ログイン」ルートがあります。session.isAuthenticated何らかの理由で、「インデックス」への移行中に値がすぐにキャッチされないようです。これがなぜなのかはわかりませんが、それは別の問題です。

とにかく、私はこのアプリケーションで多くのコンポーネントを使用しており、これらのコンポーネントのほとんどはセッションから値を取得し、ルートとは無関係にストアを照会して、これらのコンポーネントを複数のルートで使用できるようにしています。ナビも例外ではありません。現在、次の作業コードがあります。

export default Ember.Component.extend({
    layout,
    session: Ember.inject.service(),
    currentUser: Ember.inject.service(),
    isAuthenticated: Ember.observer('session.isAuthenticated', function() {
        this.didReceiveAttrs();
    }),
    currentUserFullName: null,
    user: null,
    tagName: 'navbar-main',
    className: ['navbar', 'main'],
    didReceiveAttrs() {
        this._super(...arguments);

        if (this.get('session.isAuthenticated')) {
            this._setCurrentUser();
        }
    },
    _setCurrentUser() {
        this.get('currentUser').load().then(user => this.set('user', user));
    },
    onGetCurrentUser: Ember.observer('user', function() {
        this.getUser();
    }),
    getUser: function() {
        var user = this.get('user');

        if(user) {
            this.set('user', user);
            this.set('currentUserFullName', user.get('fullName'));
        } else {
            user = this.get('store').findRecord('user', 'me');
            this.set('user', user);
            this.set('currentUserFullName', user.get('fullName'));
        }
    }
});

私が読んでいるものはすべてdidReceiveAttrs()、オブザーバーの代わりに使用することを示唆しています。また、計算されたプロパティは通常、オブザーバーよりも使用したいものであると言われています。ただし、次のものがないと何も機能しないようです。

isAuthenticated: Ember.observer('session.isAuthenticated', function() {
    this.didReceiveAttrs();
}),

それを計算されたプロパティに変換しようとすると、「インデックス」ルートに既に移行した後にページを更新しない限り、プロパティの変更に対して何もしないようです。this.get('session.isAuthenticated') ロジックでメソッドだけを使用しようとするとdidReceiveAttrs()、ページの更新が必要です。

Ember.computedでは、 and の使用方法について何が理解できませんdidReceiveAttrs()か? 誰かが私に例を挙げてもらえますか? または、私が達成しようとしていることをより効率的に行う方法を教えてください。

更新されたコード:

// app/pods/components/navbar-main/component.js
import Ember from 'ember';
import layout from './template'; 

export default Ember.Component.extend({
    layout,
    session: Ember.inject.service(),
    currentUser: Ember.inject.service(),
    user: null,
    isAuthenticated: Ember.observer('session.isAuthenticated', function() {
        this.get('currentUser').load().then(user => this.set('user', user));
    }),
    currentUserFullName: Ember.computed.alias('user.fullName'),
    tagName: 'navbar-main',
    className: ['navbar', 'main'],
    didReceiveAttrs() {
        this._super(...arguments);

        if(this.get('session.isAuthenticated')) {
            this.isAuthenticated();
        }
    }
});

<!-- app/pods/components/navbar-main/template.hbs -->
{{#if session.isAuthenticated}}
    <div class="ui black user login label">
        <div class="ui grid">
            <div class="twelve wide column">
                <div class="detailed">{{currentUserFullName}}<br>Welcome</div>
            </div>
            <div class="four wide column" style="padding-top: 12px; margin-top: 0;">
                <img class="ui top aligned small avatar image" src="http://semantic-ui.com/images/avatar/small/christian.jpg">
                <!--<img class="ui top aligned tiny avatar image" src="{{currentUser.avatar}}">-->
            </div>
        </div>
    </div>
{{/if}}

更新 2 (@AdamCooper と @kumkanillam の助けを借りた最終コード):

export default Ember.Component.extend({
    layout,
    session: Ember.inject.service(),
    currentUser: Ember.inject.service(),
    user: null,
    isAuthenticated: Ember.on('init', Ember.observer('session.isAuthenticated', function() {
        this.get('currentUser').load().then(user => this.set('user', user));
    })),
    currentUserFullName: Ember.computed.alias('user.fullName'),
    tagName: 'navbar-main',
    className: ['navbar', 'main']
});

したがって、これは最小限のコードであり、オブザーバーと計算されたメソッドを引き続き使用しますが、コンポーネントのライフサイクルは使用しません。だから、私が思いついたのは、オブザーバーを時々使用することがまだ必要だと思います。

4

3 に答える 3

2

Ember は、レンダリング シナリオに従って、コンポーネントのライフサイクル フック メソッドを順番に呼び出します。

初期レンダリング時 - init,didReceiveAttrs,willRender,didInsertElement,didRender
再リナー時 - didUpdateAttrs,didReceiveAttrs,willUpdate,willRender,didRender
コンポーネント破棄時 - willDestroyElement,willClearRender,didDestroyElement
(参照 - https://guides.emberjs.com/v2 .7.0/コンポーネント/コンポーネントのライフサイクル/ )

これらのコンポーネント ライフサイクル フック メソッドを呼び出すべきではありません。

currentUser 固有のコードを currentUser サービスに完全に分離できるため、すべてのコンポーネントに簡単に挿入して使用できると思います。

export default Ember.Component.extend({
    session: Ember.inject.service(),
    currentUser: Ember.inject.service(),
    currentUserFullName: Ember.computed.alias('currentUser.currentUserFullName'),
    user: Ember.computed.alias('currentUser.user'),

    tagName: 'navbar-main',
    className: ['navbar', 'main'],    

});

session.isAuthenticated プロパティを観察して、currentUser とその詳細を初期化します。

services\current-user.js

import Ember from 'ember';

export default Ember.Service.extend({
  session: Ember.inject.service(),
  currentUserFullName: null,
  user: null,

  loadCurrentUserDetails:Ember.observer('session.isAuthenticated', function(){
    //load async data and set user and currentUserFullName.
  })
});
于 2016-08-23T19:18:34.747 に答える
0

これは私が最終的に私の状況でうまくいったものです:

export default Ember.Component.extend({
    layout,
    session: Ember.inject.service(),
    currentUser: Ember.inject.service(),
    user: null,
    isAuthenticated: Ember.on('init', Ember.observer('session.isAuthenticated', function() {
        this.get('currentUser').load().then(user => this.set('user', user));
    })),
    currentUserFullName: Ember.computed.alias('user.fullName'),
    tagName: 'navbar-main',
    className: ['navbar', 'main']
});

これは、この質問に対するEmber FreakAdam Cooperの回答を組み合わせて使用​​しています。

于 2018-09-27T12:34:55.613 に答える