huli
contact me: aszx87410@gmail.com
huli@netappstore.net
Reference: https://facebook.github.io/react/
通知系統
function appendNewMessage(msg){
$target = null;
if(msg.type=="NEWS"){
$target = $("#news_list");
}else{
$target = $("#events_list");
}
$target.append(
'<div class="row">'+
'<div class="title">'+msg.title+'</div>'+
'<div class="content">'+msg.content+'</div>'+
'</div>'
);
}
如果事情再變的麻煩一點...
function readMessage(){
$(this).attr('read', true);
$(this).addClass('read');
}
function deleteMessage(msg){
$(this).remove();
}
有沒有可能,有一種更簡便的方式?
有沒有可能,我可以少寫一點code?
有沒有可能,我可以這樣子...
var messages = [];
function renderAll(){
messages.forEach(function(item){
var read = item.read?"read":"";
render(
<div class="row " + read>
<div class="title">item.title</div>
<div class="content">item.content</div>
</div>
);
});
}
function addMessage(msg){
messages.push(msg);
renderAll();
}
function deleteMessage(msg){
messages.find(msg.id).remove;
renderAll();
}
function readMessage(msg){
messages.find(msg.id).read = true;
renderAll();
}
優點
缺點
render: function() {
return (
<div>
<h3>TODO</h3>
<TodoList items={this.state.items} />
<form onSubmit={this.handleSubmit}>
<input onChange={this.onChange} value={this.state.text} />
<button>{'Add #' + (this.state.items.length + 1)}</button>
</form>
</div>
);
}
Facebook官方範例
Flux is the application architecture that Facebook uses for building client-side web applications.
It complements React's composable view components by utilizing a unidirectional data flow
reference: https://facebook.github.io/flux/
var PubcastListItem = React.createClass({
render: function() {
//接收上層傳來的message
var message = this.props.message;
return (
<li>
<a href={message.url} onClick={this._onClick}>
<h1>{message.message_text}</h1>
{getDate(message.timestamp)}
</a>
</li>
);
},
_onClick: function(){
PubcastActionCreators.clickMessage(this.props.message._id);
}
});
//獲得資料
function getStateFromStores() {
return {
messages: MessageStore.getAll()
};
}
//得到所有ListItem
function getMessageListItem(message) {
return (
<PubcastListItem
message={message}
/>
);
}
//從type決定資料
function isType(type){
return function(obj){
return obj.message_type==type;
}
}
var Pubcastpanel = React.createClass({
getInitialState: function() {
return {};
},
componentDidMount: function() {
MessageStore.addChangeListener(this._onChange);
},
componentWillUnmount: function() {
MessageStore.removeChangeListener(this._onChange);
},
//把message分類別 render
render: function() {
var newMessageListItems = [];
var eventMessageListItems = [];
if(this.state.messages){
newMessageListItems = this.state.messages.filter(isType(4)).map(getMessageListItem);
eventMessageListItems = this.state.messages.filter(isType(1)).map(getMessageListItem);
}
return (
<div>
<div className="back">Back</div>
<ul>
<li>
<a className="gift">Pubgame Gift</a>
<div className="newnumber">
</div>
</li>
<li className="news">NEWS</li>
<ul className="list">
{newMessageListItems}
</ul>
<li className="event">EVENTS</li>
<ul className="list ev">
{eventMessageListItems}
</ul>
</ul>
</div>
);
},
_onChange: function() {
this.setState(getStateFromStores());
}
});
module.exports = Pubcastpanel;
var ActionTypes = PubcastConstants.ActionTypes;
module.exports = {
//跟dispatcher說:我收到資料囉
receiveAll: function(rawMessages) {
PubcastAppDispatcher.dispatch({
type: ActionTypes.RECEIVE_RAW_MESSAGES,
rawMessages: rawMessages
});
},
//新訊息
receiveNewMessage: function(newMessage) {
PubcastAppDispatcher.dispatch({
type: ActionTypes.RECEIVE_NEW_MESSAGE,
rawMessages: newMessage
});
},
//點擊某訊息
clickMessage: function(_id){
PubcastAppDispatcher.dispatch({
type: ActionTypes.CLICK_MESSAGE,
_id: _id
});
}
};
var ActionTypes = PubcastConstants.ActionTypes;
var CHANGE_EVENT = 'change';
var _messages = {};
var _unreadCount = 0;
//獲取全部訊息
function _addMessages(rawMessages) {
_messages = rawMessages;
//計算未讀數量
rawMessages.forEach(function(msg){
if(msg.unread===true){
_unreadCount++;
}
});
}
//新增新訊息
function _newMessages(rawMessages){
rawMessages = [rawMessages];
rawMessages.forEach(function(msg){
msg.unread=true;
msg._id = msg.message_id;
msg.timestamp = msg.message_time;
_messages.unshift(msg);
_unreadCount++;
});;
}
var MessageStore = assign({}, EventEmitter.prototype, {
emitChange: function() {
this.emit(CHANGE_EVENT);
},
addChangeListener: function(callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function(callback) {
this.removeListener(CHANGE_EVENT, callback);
},
get: function(id) {
return _messages[id];
},
getAll: function() {
return _messages;
},
getUnreadCount: function(){
return _unreadCount;
}
});
//跟dispacher註冊事件
//當有人觸發「ActionTypes.RECEIVE_RAW_MESSAGES」時就知道有新訊息
MessageStore.dispatchToken = PubcastAppDispatcher.register(function(action) {
switch(action.type) {
//獲取全部訊息
case ActionTypes.RECEIVE_RAW_MESSAGES:
_addMessages(action.rawMessages);
MessageStore.emitChange();
break;
//收到新訊息
case ActionTypes.RECEIVE_NEW_MESSAGE:
_newMessages(action.rawMessages);
MessageStore.emitChange();
break;
//有人點擊訊息
case ActionTypes.CLICK_MESSAGE:
//標記為已讀
_unreadCount--;
_messages.forEach(function(item){
if(item._id===action._id){
item.unread = false;
return;
}
});
//跟server講
PubcastAPIUtils.clickMessage(action._id);
MessageStore.emitChange();
default:
// do nothing
}
});
module.exports = MessageStore;
module.exports = {
init: function(){
//初始化pubcast,與server連線
Pubcast.init(..., {
//獲取全部訊息
getAllActiveMessage: function(data){
PubcastActionCreators.receiveAll(data.activeMessages);
},
//新訊息
notifyNewMessage: function(data){
PubcastActionCreators.receiveNewMessage(data.newMessage);
}
});
},
clickMessage: function(id){
Pubcast.updateClickEvent(id);
},
getAllMessages: function() {
//利用action creator 送給dispatcher event
PubcastActionCreators.receiveAll(rawMessages);
}
};
By huli
簡單分享一下自己初學React跟Flux的心得