Javascript React-LinkedStateMixin存在问题
我尝试在ReactJs上进行双向绑定,并尝试使用LinkedStateMixin。根据React网站,从React 0.14开始,所有插件都已移动到单独的软件包中:因此,我通过npm安装了React插件链接状态mixin,但在尝试使用它时出现以下错误:Javascript React-LinkedStateMixin存在问题,javascript,reactjs,Javascript,Reactjs,我尝试在ReactJs上进行双向绑定,并尝试使用LinkedStateMixin。根据React网站,从React 0.14开始,所有插件都已移动到单独的软件包中:因此,我通过npm安装了React插件链接状态mixin,但在尝试使用它时出现以下错误: Uncaught TypeError: this.linkState is not a function 我的代码是: import React, { PropTypes } from 'react'; import TimelineEvent
Uncaught TypeError: this.linkState is not a function
我的代码是:
import React, { PropTypes } from 'react';
import TimelineEvent from './TimelineEvent';
import {TimelineEditButton} from './TimelineEvent';
import styles from './Main.css';
import withStyles from '../../../../decorators/withStyles';
import MainView from '../../../MainView';
import SwapBlock from '../../../SwapBlock';
import RoundButton from '../../../RoundButton';
import LightBox from '../../../LightBox';
import Dropzone from 'react-dropzone';
import classnames from 'classnames';
import LinkedStateMixin from 'react-addons-linked-state-mixin';
@withStyles(styles)
class Main extends React.Component {
render() {
let session = this.props.session
let user = this.props.user
return (
<MainView>
<Timeline session={session} user={user} />
</MainView>
);
}
}
class Timeline extends React.Component {
// Hide all Partials
constructor() {
super();
this.state = {
eventTitle: '',
eventPlace: '',
eventLocation: '',
eventDescription: ''
};
this.state['addEventPartial'] = false;
this.state.files = [];
}
openPartial(tag) {
var tags = {};
tags[tag] = true;
this.setState(tags);
var e = document.getElementById("add-timeline-event");
if (!!e && e.scrollIntoView) {
e.scrollIntoView();
}
}
closePartial(tag) {
var tags = {};
tags[tag] = false;
this.setState(tags);
}
openLightbox(tag) {
var tags = {};
tags[tag] = true;
this.setState(tags);
}
closeLightbox(tag) {
var tags = {};
tags[tag] = false;
this.setState(tags);
}
getPartial(tag)
{
return this.state[tag];
}
getLightbox(tag)
{
return this.state[tag];
}
onDrop(files) {
console.log('Received files: ', files);
this.setState({
files: files
});
}
render() {
let session = this.props.session
let user = this.props.user
let isAuth = session.isAuth
let addEvent = {}
let events = []
let data = [{
id: "123",
key: "1",
type: "academic",
time: "2015 - 2016",
title: " MSc Software Engineering",
place: "University of Oxford",
location: "Oxford, United Kingdom",
description: "Lorem impsum",
gallery: []
},{
id: "234",
key: "2",
type: "professional",
time: "2015 - 2016",
title: " MSc Software Engineering",
place: "University of Oxford",
location: "Oxford, United Kingdom",
description: "Lorem impsum",
gallery: [
{url: "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/v/t1.0-1/p160x160/10923196_10204583699694173_6145976884213630323_n.jpg?oh=bd235908314ecf0ab5afa8d3f92f5abf&oe=567B51F9&__gda__=1450897067_285c7c8c720c0f130453b37e9ff9b2f8"}
]
},{
id: "567",
key: "3",
type: "misc",
time: "2015 - 2016",
title: " MSc Software Engineering",
place: "University of Oxford",
location: "Oxford, United Kingdom",
description: "Lorem impsum",
gallery: [{
index: 1,
url: "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/v/t1.0-1/p160x160/10923196_10204583699694173_6145976884213630323_n.jpg?oh=bd235908314ecf0ab5afa8d3f92f5abf&oe=567B51F9&__gda__=1450897067_285c7c8c720c0f130453b37e9ff9b2f8"
}]
}]
// Loop through all Timeline Events
for (var i = 0; i < data.length; i++) {
let directions;
let gallery = [];
if (i % 2 == 0) {
directions = "direction-r";
} else {
directions = "direction-l"
}
for (var j = 0; j < data[i].gallery.length; j++) {
gallery.push(
<a onClick={this.openLightbox.bind(this, "galleryLightbox")}><img alt={data[i].title} className="TimelineViewGalleryImage" src={data[i].gallery[j].url} /></a>
)}
events.push(
<li>
<TimelineEvent
key = {data[i].id}
type={data[i].type}
time = {data[i].time}
title = {data[i].title}
place = {data[i].place}
location = {data[i].location}
description = {data[i].description}
direction = {directions}
session = {session}
user = {user}>
{gallery}
<TimelineEditButton deleteClick={this.openPartial.bind(this, "addEventPartial")}
editClick={this.openPartial.bind(this, "addEventPartial")}
session={session} user={user} eventId={data[i].id} />
</TimelineEvent>
</li>
)
}
// Add Event to timeline Dialog
if (isAuth){
addEvent = (
<form className="AddEventForm">
<SwapBlock show={!this.getPartial("addEventPartial")}>
<div className="AddEventButton">
<RoundButton onClick={this.openPartial.bind(this, "addEventPartial")} color="green">
<span className="EventPlus">+</span>
</RoundButton>
</div>
</SwapBlock>
<SwapBlock show={this.getPartial("addEventPartial")}>
<div className="TimelineBackdrop"></div>
<div className="AddTimelineEvent">
<button className="AddTimelineEventCloseButton" onClick={this.closePartial.bind(this, "addEventPartial")}>
<i className="fa fa-times"></i>
</button>
<h3>Add Event</h3>
<div className="AddEventTitle TimelineFormField">
<input value={eventTitle} className="TimelineInput" placeholder="Title" />
</div>
<div className="AddEventPlace TimelineFormField">
<input valueLink={this.linkState('eventPlace')} className="TimelineInput" placeholder="Place" />
</div>
<div className="AddEventLocation TimelineFormField">
<input valueLink={this.linkState('eventLocation')} className="TimelineInput" placeholder="Location" />
</div>
<div className="AddEventDescription TimelineFormField">
<textarea valueLink={this.linkState('eventDescription')} rows="2" className="TimelineInput" placeholder="Description"></textarea>
</div>
<StartDateSelect />
<EndDateSelect />
<EventTypeSelect />
<div className="AddEventMedia TimelineFormField">
<Dropzone className="Dropzone" activeClassName="DropzoneActive" ref="dropzone" multiple={true} disableClick={false} onDrop={this.onDrop.bind(this)}>
<div>Try dropping some files here, or click to select files to upload.</div>
{this.state.files.length > 0 ?
<div>
<div>{this.state.files.map((file) =>
<div className="DropzoneUploadedImageContainer">
<img className="DropzoneUploadedImage" src={file.preview} />
<br className="clear" />
</div> )}
</div>
<p className="DropzoneFileCount">{this.state.files.length} files</p>
</div> : null}
</Dropzone>
<p className="AddTimelineEventNote">Note: Images only, maximum 4 images and maximum file size is 2 MB</p>
<button className="SaveEventButton btn btn-primary">Save</button>
<button onClick={this.closePartial.bind(this, "addEventPartial")} className="SaveEventButton btn btn-default">Cancel</button>
</div>
</div>
</SwapBlock>
<SwapBlock show={this.getPartial("addEventPartial")}>
<div className="TimelineSeparator"></div>
</SwapBlock>
</form>
);
}
// Render Timeline
return (
<div className="Timeline">
<LightBox show={this.getLightbox("galleryLightbox")}>
<button className="TimelineGalleryCloseButton" onClick={this.closeLightbox.bind(this, "galleryLightbox")}>
<i className="fa fa-times"></i>
</button>
<img src="https://d13yacurqjgara.cloudfront.net/users/14268/screenshots/1934662/taptap_1x.png" />
</LightBox>
<h3><span className="TimelineHeading">Timeline</span>
<div className="TimelineNav">
<button href="#" className="allFilter active">All</button>
<button href="#" className="professionalFilter">Professional</button>
<button href="#" className="academicFilter">Academic</button>
<button href="#" className="miscFilter">Miscellaneous</button>
</div>
<br className="clear" />
</h3>
<div className="TimelineContainer" id="add-timeline-event">
{addEvent}
<ul className="TimelineView">
{events}
</ul>
</div>
</div>
);
}
}
class StartDateSelect extends React.Component {
render() {
return(
<div className="AddEventDescription TimelineFormField">
<h5 className="EventTypeField EventDateField"><span className="EventTypeLabel">Start Date</span></h5>
<div className="EventDateContainer">
<select className="TimelineFormField">
<option selected disabled>Year:</option>
<option value="--">--</option>
<option value="01">2015</option>
<option value="02">2014</option>
<option value="03">2013</option>
</select>
<select className="TimelineFormField">
<option selected disabled>Month:</option>
<option value="--">--</option>
<option value="January">December</option>
<option value="February">November</option>
<option value="March">October</option>
</select>
<select className="TimelineFormField">
<option selected disabled>Day:</option>
<option value="--">--</option>
<option value="2014">31</option>
<option value="2015">30</option>
<option value="2016">29</option>
</select>
</div>
<br className="clear" />
</div>
);
}
}
class EndDateSelect extends React.Component {
render() {
return(
<div className="AddEventDescription TimelineFormField">
<h5 className="EventTypeField EventDateField"><span className="EventTypeLabel">End Date</span></h5>
<div className="EventDateContainer">
<select className="TimelineFormField">
<option selected disabled>Year:</option>
<option value="--">--</option>
<option value="01">2015</option>
<option value="02">2014</option>
<option value="03">2013</option>
</select>
<select className="TimelineFormField">
<option selected disabled>Month:</option>
<option value="--">--</option>
<option value="January">December</option>
<option value="February">November</option>
<option value="March">October</option>
</select>
<select className="TimelineFormField">
<option selected disabled>Day:</option>
<option value="--">--</option>
<option value="2014">31</option>
<option value="2015">30</option>
<option value="2016">29</option>
</select>
</div>
<br className="clear" />
</div>
);
}
}
class EventTypeSelect extends React.Component {
render() {
return(
<div className="AddEventDescription TimelineFormField">
<h5 className="EventTypeField"><span className="EventTypeLabel">Event Type</span>
<button className="EventTypeFieldProfessional"><span className="TypeDot"></span>Professional</button>
<button className="EventTypeFieldAcademic"><span className="TypeDot"></span>Academic</button>
<button className="EventTypeFieldMiscellaneous"><span className="TypeDot"></span>Miscellaneous</button>
</h5>
</div>
);
}
}
export default Main;
import React,{PropTypes}来自'React';
从“/TimelineEvent”导入TimelineEvent;
从“/TimelineEvent”导入{TimelineEditButton};
从“/Main.css”导入样式;
从“../../../../../decorators/withStyles”导入withStyles;
从“../../../MainView”导入MainView;
从“../../../SwapBlock”导入SwapBlock;
从“../../../RoundButton”导入RoundButton;
从“../../../LightBox”导入LightBox;
从“react Dropzone”导入Dropzone;
从“类名称”导入类名称;
从“react addons linked state mixin”导入LinkedStateMixin;
@样式(样式)
类Main扩展了React.Component{
render(){
让session=this.props.session
让user=this.props.user
返回(
);
}
}
类。组件{
//隐藏所有部分
构造函数(){
超级();
此.state={
eventTitle:“”,
事件地点:“”,
事件位置:“”,
事件描述:“”
};
此.state['addEventPartial']=false;
this.state.files=[];
}
openPartial(标记){
var标签={};
tags[tag]=true;
此设置状态(标签);
var e=document.getElementById(“添加时间线事件”);
如果(!!e&&e.scrollIntoView){
e、 scrollIntoView();
}
}
关闭部分(标记){
var标签={};
tags[tag]=false;
此设置状态(标签);
}
openLightbox(标签){
var标签={};
tags[tag]=true;
此设置状态(标签);
}
封闭灯箱(标签){
var标签={};
tags[tag]=false;
此设置状态(标签);
}
getPartial(标记)
{
返回此.state[tag];
}
getLightbox(标签)
{
返回此.state[tag];
}
onDrop(文件){
log('Received files:',files);
这是我的国家({
文件:文件
});
}
render(){
让session=this.props.session
让user=this.props.user
让isAuth=session.isAuth
设addEvent={}
让事件=[]
让数据=[{
身份证号码:“123”,
关键:“1”,
类型:“学术”,
时间:“2015-2016”,
标题:“软件工程硕士”,
地点:“牛津大学”,
地点:“英国牛津”,
描述:“奥勒姆·英普苏姆”,
画廊:[]
},{
id:“234”,
键:“2”,
类型:“专业”,
时间:“2015-2016”,
标题:“软件工程硕士”,
地点:“牛津大学”,
地点:“英国牛津”,
描述:“奥勒姆·英普苏姆”,
画廊:[
{url:“https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/v/t1.0-1/p160x160/10923196_10204583699694173_6145976884213630323_n.jpg?oh=bd235908314ecf0ab5afa8d3f92f5abf&oe=567B51F9&__gda__=1450897067_285c7c8c720c0f130453b37e9ff9b2f8"}
]
},{
身份证号码:“567”,
关键:“3”,
类型:“杂项”,
时间:“2015-2016”,
标题:“软件工程硕士”,
地点:“牛津大学”,
地点:“英国牛津”,
描述:“奥勒姆·英普苏姆”,
画廊:[{
索引:1,
url:“https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash2/v/t1.0-1/p160x160/10923196_10204583699694173_6145976884213630323_n.jpg?oh=bd235908314ecf0ab5afa8d3f92f5abf&oe=567B51F9&__gda__=1450897067_285c7c8c720c0f130453b37e9ff9b2f8"
}]
}]
//循环浏览所有时间轴事件
对于(变量i=0;i
{画廊}
)
}
//“将事件添加到时间轴”对话框
if(isAuth){
addEvent=(
+
添加事件
尝试在此处删除一些文件,或单击以选择要上载的文件。
{this.state.files.length>0?
{this.state.files.map((文件)=>
)}
{this.state.files.length}文件
:null}
注意:仅图像,最多4个图像,最大文件大小为2MB
拯救
取消
);
}
//渲染时间轴
返回(
时间线
全部的
专业的
学术的
混杂的
{addEvent}
{events}
);
}
}
类StartDateSelect扩展了React.Component{
render(){
返回(
开始日期
年份:
--
2015
20
class Something extends React.Component {
state = {
email: ''
}
emailValueLink = (value) => {
return {
value: this.state.email,
requestChange: this.handleEmailChange
};
}
handleEmailChange(newEmail) {
this.setState({email: newEmail});
}
render() {
<input type="email" valueLink={this.emailValueLink()} />
}
}