如何让 mixin 填充状态 ES6 模块?
How to make mixin populate state ES6 module?
在 _getUserProfile()
为 运行 并且宿主属性被填充后,使用 UserProfileMixin
的其他元素不会获得已填充的属性,它们只会变得未填充默认值。像 this.profile
将是 {}
而不是配置文件。
为什么会这样,我怎样才能让这个 mixin 从 mixin 中填充 es6 模块 user-profile-state.js
?
注意:对使用 Redux 不感兴趣,我对 ES6 模块作为状态管理很满意。仅在 Mixins 中存在问题。
% cat app/account/user-profile-state.js
const profile = {};
let isLoggedIn = false;
let profilePic;
export {
isLoggedIn,
profile,
profilePic,
};
% cat app/account/user-profile.js
import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';
import '@polymer/paper-button/paper-button.js';
import { PauseForRipple } from '../mixins/pause-for-ripple-mixin.js';
import { FetchMixins } from '../mixins/fetch-mixins.js';
import { HOST } from '../constants.js';
import { UserProfileMixin } from '../mixins/user-profile-mixin.js';
import {
isLoggedIn,
profile,
profilePic,
} from '../account/user-profile-state.js';
class UserProfile extends UserProfileMixin(FetchMixins(PauseForRipple(PolymerElement))) {
static get template() {
return html`
<style>
:host {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 10px;
height: 100%;
}
.login-text, .login-text-small {
color: var(--primary-text);
font-size: 25px;
font-weight: 300;
}
.login-text-small {
font-size: 15px;
}
--paper-input-container-color: red;
.login-container {
width: 250px;
height: 100%;
padding: 25px;
display: flex;
justify-content: center;
}
paper-material {
height: 100%;
border-radius: 2px;
}
paper-button {
background-color: #fff;
color: var(--button-text);
width: 190px;
font-size: 12px;
}
a {
text-decoration: none;
}
</style>
<div>First Name: [[profilePic]]</div>
`;
}
static get properties() {
return {
isLoggedIn: {
type: Boolean,
value: isLoggedIn,
},
profile: {
type: Object,
value: profile,
},
profilePic: {
type: String,
value: profilePic,
},
};
}
ready() {
super.ready();
console.log(this.profile);
console.log(this.isLoggedIn);
}
}
% cat app/mixins/user-profile-mixin.js
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
import { USER_PROFILE } from '../constants'; // host url
import {
isLoggedIn,
profile,
profilePic,
} from '../account/user-profile-state.js';
let rawUserProfileMixin = (base) => {
class foo extends base {
constructor() {
super();
}
static get properties() {
return {
// this is for host url
USER_PROFILE: {
type: String,
value: USER_PROFILE,
},
isLoggedIn: {
type: Boolean,
value: isLoggedIn,
},
profile: {
type: Object,
value: profile,
},
profilePic: {
type: String,
value: profilePic,
},
};
}
_getUserProfile() {
var url = `${this.HOST}${this.USER_PROFILE}`;
var request = this.createRequest(url);
fetch(request)
.then(this.fetchError)
.then(this.json)
.then((response) => {
if (response.profile) {
console.log('aaa');
this.isLoggedIn = true;
this.profilePic = response.profile.pic;
this.profile = Object.assign({}, response.profile);
}
})
.catch((e) => {
this.isLoggedIn = false;
console.log('error in checking logged in mixin ' + e);
});
}
ready() {
super.ready();
}
}
return foo;
};
export const UserProfileMixin = dedupingMixin(rawUserProfileMixin);
解决方案是制作访问器函数(参见 airbnb JS 样式指南)。
let profile = {};
let isLoggedIn = false;
let profilePic;
const setProfile = (newValue) => {
if (newValue) {
profile = Object.assign({}, newValue);
isLoggedIn = true;
profilePic = profile.pic;
} else {
profile = null;
isLoggedIn = false;
profilePic = null;
}
}
export {
isLoggedIn,
profile,
profilePic,
setProfile,
};
混音:
import {
isLoggedIn,
profile,
profilePic,
setProfile,
} from '../account/user-profile-state.js';
let rawUserProfileMixin = (base) => {
class foo extends base {
constructor() {
super();
}
static get properties() {
return {
// this is for host url
USER_PROFILE: {
type: String,
value: USER_PROFILE,
},
isLoggedIn: {
type: Boolean,
value: isLoggedIn,
},
profile: {
type: Object,
value: profile,
},
profilePic: {
type: String,
value: profilePic,
},
};
}
_getUserProfile() {
var url = `${this.HOST}${this.USER_PROFILE}`;
var request = this.createRequest(url);
fetch(request)
.then(this.fetchError)
.then(this.json)
.then((response) => {
setProfile(response.profile);
})
.catch((e) => {
this.isLoggedIn = false;
console.log('error in checking logged in mixin ' + e);
});
}
在 _getUserProfile()
为 运行 并且宿主属性被填充后,使用 UserProfileMixin
的其他元素不会获得已填充的属性,它们只会变得未填充默认值。像 this.profile
将是 {}
而不是配置文件。
为什么会这样,我怎样才能让这个 mixin 从 mixin 中填充 es6 模块 user-profile-state.js
?
注意:对使用 Redux 不感兴趣,我对 ES6 模块作为状态管理很满意。仅在 Mixins 中存在问题。
% cat app/account/user-profile-state.js
const profile = {};
let isLoggedIn = false;
let profilePic;
export {
isLoggedIn,
profile,
profilePic,
};
% cat app/account/user-profile.js
import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';
import '@polymer/paper-button/paper-button.js';
import { PauseForRipple } from '../mixins/pause-for-ripple-mixin.js';
import { FetchMixins } from '../mixins/fetch-mixins.js';
import { HOST } from '../constants.js';
import { UserProfileMixin } from '../mixins/user-profile-mixin.js';
import {
isLoggedIn,
profile,
profilePic,
} from '../account/user-profile-state.js';
class UserProfile extends UserProfileMixin(FetchMixins(PauseForRipple(PolymerElement))) {
static get template() {
return html`
<style>
:host {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 10px;
height: 100%;
}
.login-text, .login-text-small {
color: var(--primary-text);
font-size: 25px;
font-weight: 300;
}
.login-text-small {
font-size: 15px;
}
--paper-input-container-color: red;
.login-container {
width: 250px;
height: 100%;
padding: 25px;
display: flex;
justify-content: center;
}
paper-material {
height: 100%;
border-radius: 2px;
}
paper-button {
background-color: #fff;
color: var(--button-text);
width: 190px;
font-size: 12px;
}
a {
text-decoration: none;
}
</style>
<div>First Name: [[profilePic]]</div>
`;
}
static get properties() {
return {
isLoggedIn: {
type: Boolean,
value: isLoggedIn,
},
profile: {
type: Object,
value: profile,
},
profilePic: {
type: String,
value: profilePic,
},
};
}
ready() {
super.ready();
console.log(this.profile);
console.log(this.isLoggedIn);
}
}
% cat app/mixins/user-profile-mixin.js
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
import { USER_PROFILE } from '../constants'; // host url
import {
isLoggedIn,
profile,
profilePic,
} from '../account/user-profile-state.js';
let rawUserProfileMixin = (base) => {
class foo extends base {
constructor() {
super();
}
static get properties() {
return {
// this is for host url
USER_PROFILE: {
type: String,
value: USER_PROFILE,
},
isLoggedIn: {
type: Boolean,
value: isLoggedIn,
},
profile: {
type: Object,
value: profile,
},
profilePic: {
type: String,
value: profilePic,
},
};
}
_getUserProfile() {
var url = `${this.HOST}${this.USER_PROFILE}`;
var request = this.createRequest(url);
fetch(request)
.then(this.fetchError)
.then(this.json)
.then((response) => {
if (response.profile) {
console.log('aaa');
this.isLoggedIn = true;
this.profilePic = response.profile.pic;
this.profile = Object.assign({}, response.profile);
}
})
.catch((e) => {
this.isLoggedIn = false;
console.log('error in checking logged in mixin ' + e);
});
}
ready() {
super.ready();
}
}
return foo;
};
export const UserProfileMixin = dedupingMixin(rawUserProfileMixin);
解决方案是制作访问器函数(参见 airbnb JS 样式指南)。
let profile = {};
let isLoggedIn = false;
let profilePic;
const setProfile = (newValue) => {
if (newValue) {
profile = Object.assign({}, newValue);
isLoggedIn = true;
profilePic = profile.pic;
} else {
profile = null;
isLoggedIn = false;
profilePic = null;
}
}
export {
isLoggedIn,
profile,
profilePic,
setProfile,
};
混音:
import {
isLoggedIn,
profile,
profilePic,
setProfile,
} from '../account/user-profile-state.js';
let rawUserProfileMixin = (base) => {
class foo extends base {
constructor() {
super();
}
static get properties() {
return {
// this is for host url
USER_PROFILE: {
type: String,
value: USER_PROFILE,
},
isLoggedIn: {
type: Boolean,
value: isLoggedIn,
},
profile: {
type: Object,
value: profile,
},
profilePic: {
type: String,
value: profilePic,
},
};
}
_getUserProfile() {
var url = `${this.HOST}${this.USER_PROFILE}`;
var request = this.createRequest(url);
fetch(request)
.then(this.fetchError)
.then(this.json)
.then((response) => {
setProfile(response.profile);
})
.catch((e) => {
this.isLoggedIn = false;
console.log('error in checking logged in mixin ' + e);
});
}