i'm trying to write a module in rivets.js.
When i create a component with another nested component, the model is not in sync.
I just cant figure.
How do i sync value of hash to be same in the parent and child component?
Thank you.
Here is the fiddle (pen): http://codepen.io/anon/pen/qNmNJO?editors=1010
rivets.formatters.log = (data) => {
console.log(data);
};
rivets.formatters.filter = (items, arg) => {
console.log(items);
items = items.filter((item) => {
return item[arg];
});
return items;
};
rivets.formatters.eq = (value, arg) => {
return value == arg;
};
rivets.formatters.gt = (value, arg) => {
return value > arg;
};
rivets.formatters.lt = (value, arg) => {
return value < arg;
};
function ItemList(attributes) {
this.data = attributes;
this.checkbox_change = function(e, data) {
data.data.hash++;
};
}
rivets.components['item-list'] = {
template: function() {
return `
<div class="dest_wrap" rv-each-destination="data.destinations">
<label>
<input data-type="country" rv-on-click="checkbox_change" rv-checked="destination.selected" type="checkbox">
{ destination.name }
</label>
{ data.hash | log }
<span rv-text="data.hash"></span>
</div>
`;
},
initialize: function(el, attributes) {
return new ItemList(attributes);
}
};
// https://github.com/whayler1/rivets-example
let model = {
hash: 0,
destination_tree: [{
name: 'Itálie',
selected: false,
id: 1
}, {
name: 'Chorvatsko',
selected: true,
id: 2
}, {
name: 'Bulharsko',
selected: true,
id: 3
}],
};
function DestinationPicker(attributes) {
this.data = attributes;
}
rivets.components['destination-picker'] = {
template: function() {
return `
<div>
<item-list
hash="data.hash"
destinations=".data.destinations"
level="'countries'"
/>
</div>
<input type="number" rv-value="data.hash">
<span rv-text="data.hash"></span>
`;
},
initialize: function(el, attributes) {
return new DestinationPicker(attributes);
}
};
window.rivets_view = rivets.bind($('destination-picker'), model); // K čemu mohou přistupovat elementy
<script src="https://cdnjs.cloudflare.com/ajax/libs/rivets/0.9.0/rivets.bundled.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<main class="row">
<destination-picker destinations="destination_tree" hash="hash"></destination-picker>
</main>
Related
Could I use method call from mounted function?
in my code, I used this method.
mounted() {
this.initEvent();
this.getnewD(
$(function () {
$("#file-manager").dxFileManager({
name: "fileManager",
fileSystemProvider: customProvider,
currentPath: "Documents",
rootFolderName: "Root",
height: 450,
onErrorOcurred: function (e) {
debugger;
console.log(e);
},
permissions: {
create: true,
copy: true,
move: true,
delete: true,
rename: true,
},
customizeDetailColumns: (columns) => {
columns.push({
caption: "Creator",
dataField: "dataItem.creator",
});
return columns;
},
});
}));
},
And in my methods, I tried to used this methods to call mounted function.
But I got the customProvider is not a function.
So where has problem in my code?
methods: {
arr.forEach((item) => {
let tokens = item.path.replace(/^\/|\/$/g, "").split("/");
let current = tree;
for (let i = 0; i < tokens.length; i++) {
if (!current[tokens[i]]) {
current[tokens[i]] = {};
}
current = current[tokens[i]];
}
});
const parseNode = function (node) {
return Object.keys(node).map((key) => {
if (Object.keys(node[key]).length === 0) {
return {
isDirectory: false,
name: key,
};
}
return {
isDirectory: true,
name: key,
items: parseNode(node[key]),
};
});
};
let result = parseNode(tree);
var objectProvider =
new DevExpress.fileManagement.ObjectFileSystemProvider({
data: new_r,
});
var customProvider =
new DevExpress.fileManagement.CustomFileSystemProvider({
getItems: function (pathInfo) {
return objectProvider.getItems(pathInfo);
},
renameItem: function (item, name) {
if (item.name == "Parent1") {
console.log("error in custom provider");
throw {
errorId: 0,
fileItem: item,
};
console.log("error in custom provider");
} else return objectProvider.renameItem(item, name);
},
createDirectory: function (parentDir, name) {
if (parentDir.name == "Parent1") {
throw {
errorId: 0,
fileItem: item,
};
} else return objectProvider.createDirectory(parentDir, name);
},
deleteItem: function (item) {
console.log(item);
if (item.name == "Parent1") {
throw {
errorId: 0,
fileItem: item,
};
} else return objectProvider.deleteItems([item]);
},
moveItem: function (item, destinationDir) {
if (item.name == "Parent1") {
throw {
errorId: 0,
fileItem: item,
};
} else
return objectProvider.moveItems([item], destinationDir);
},
copyItem: function (item, destinationDir) {
if (item.name == "Parent1") {
throw {
errorId: 0,
fileItem: item,
};
} else
return objectProvider.copyItems([item], destinationDir);
},
});
let new_r = (self.fileSystemProvider = [
{
name: "Security Manager",
isDirectory: true,
items: result,
},
]);
}
I could got the data, but couldn't got some function and displayed the customProvider is not a function.
This has no proper function name in methods: { }
arr.forEach((item) => { ... }
Your methods need to be named!
You need something like that in your methods: object:
methods: {
myfunction(items) {
items.forEach((item) => {
...
}
}
Now you can call myfunction(arr) somewhere else in your script tags
mounted() works with plain js code inside because it is a named lifecycle hook. The methods: { } object however is not a function.
I am trying to make a json webapp which reads from apis and prints the result into a list.
The problem is that i cannot read the complete json object on render.
console.log(this.state.coinInfo);
coinInfo is a json object looking like:
quantstamp: {id: "quantstamp", name: "Quantstamp", symbol: "QSP", rank: "107", price_usd: "0.446127", …},
vechain: {id: "vechain", name: "VeChain", symbol: "VEN", rank: "30", price_usd: "5.80186", …}
writing:
this.state.coinInfo["vechain"] works, but
this.state.coinInfo["vechain"].id says undefined.
I would love to get the coinInfo informations into the element on render.
Here is the full code:
var Dashboard = React.createClass({
getInitialState: function() {
return {
coinListJson: "json/coinlist.json",
coinList: [],
coinInfo: {}
}
},
createDashboard: function(event) {},
componentDidMount: function() {
// Is there a React-y way to avoid rebinding `this`? fat arrow?
var th = this;
var coinListBuffer;
var coinInfoBuffer = {};
this.serverRequest = axios.get(this.state.coinListJson).then(function(result) {
coinListBuffer = result.data.coins;
th.setState({
coinList: result.data.coins
})
}).then(function() {
//alert("geht "+coinListBuffer[1].id);
coinListBuffer.map(function(val, index) {
var url = "https://api.coinmarketcap.com/v1/ticker/" + val.id + "/?convert=EUR";
th.serverRequest = axios.get(url).then(function(result) {
coinInfoBuffer[val.id] = result.data;
console.log(result.data[0]);
var coinInfoBufferString = coinInfoBuffer;
th.setState({
coinInfo: coinInfoBufferString
})
})
})
})
},
render: function() {
var th = this;
console.log(this.state.coinInfo);
return (
<ul>
{
this.state.coinList.map(function(val, index) {
return (
<li key={index}>
{val.id}
</li>);
})
}
</ul>
)
}
});
I tried to create a simple todo app with Cyclejs/xstream. The app works fine. Only thing I not able to understand is after adding each todo the input should clear, which is not happening.
todo.js
import {
div, span, p, input, ul, li, button, body
}
from '#cycle/dom'
import xs from 'xstream'
import Utils from './utils'
export function Todo(sources) {
const sinks = {
DOM: view(model(intent(sources)))
}
return sinks
}
function intent(sources) {
return {
addTodo$: sources.DOM.select('input[type=text]').events('keydown').filter((ev) => {
return ev.which == 13 && ev.target.value.trim().length > 0;
}).map((ev) => {
return ev.target.value;
}),
deleteTodo$: sources.DOM.select('.delete').events('click').map((ev) => {
return Number(ev.target.getAttribute('data-id'));
}).filter((id) => {
return !isNaN(id);
}),
completeTodo$: sources.DOM.select('.complete').events('click').map((ev) => {
return Number(ev.target.getAttribute('data-id'));
}).filter((id) => {
return !isNaN(id);
})
};
}
function model(action$) {
let deleteTodo$ = action$.deleteTodo$.map((id) => {
return (holder) => {
let index = Utils.findIndex(holder.currentTodos, 'id', id);
if (index > -1) holder.currentTodos.splice(index, 1);
return {
currentTodos: holder.currentTodos,
value: ''
};
};
});
let completeTodo$ = action$.completeTodo$.map((id) => {
return (holder) => {
let index = Utils.findIndex(holder.currentTodos, 'id', id);
if (index > -1) holder.currentTodos[index].completed = !holder.currentTodos[index].completed;
return {
currentTodos: holder.currentTodos,
value: ''
};
};
});
let addTodo$ = action$.addTodo$.map((item) => {
return (holder) => {
let todo = {
value: item,
id: holder.currentTodos.length + 1,
completed: false
};
holder.currentTodos.push(todo);
return {
currentTodos: holder.currentTodos,
value: ''
};
};
});
return xs.merge(deleteTodo$, addTodo$, completeTodo$)
.fold((holder, modifier) => {
return modifier(holder);
}, {
currentTodos: [],
value: ''
});
}
function view(state$) {
return state$.map((state) => {
console.log(state);
return div({
attrs: {
class: 'todo'
}
}, [
input({
props: {
type: 'text',
value: state.value
}
}),
ul({
attrs: {
class: 'text'
}
}, state.currentTodos.map((todo) => {
return li({
attrs: {
class: `${todo.completed ? 'completed' : 'open'}`
}
}, [
span(todo.value),
button({
attrs: {
class: 'delete',
'data-id': todo.id
}
}, 'XXXXX'),
button({
attrs: {
class: 'complete',
'data-id': todo.id
}
}, 'CCCCC')
]);
}))
]);
});
}
utils.js
var Utils = {
filter: function(array, fn) {
var results = [];
var item;
for (var i = 0, len = array.length; i < len; i++) {
item = array[i];
if (fn(item)) results.push(item);
}
return results;
},
findItem: function(array, fn) {
for (var i = 0, len = array.length; i < len; i++) {
var item = array[i];
if (fn(item)) return item;
}
return null;
},
findIndex: function(array, prop, value) {
var pointerId = -1;
var index = -1;
var top = array.length;
var bottom = 0;
for (var i = array.length - 1; i >= 0; i--) {
index = bottom + (top - bottom >> 1);
pointerId = array[index][prop];
if (pointerId === value) {
return index;
} else if (pointerId < value) {
bottom = index;
} else if (pointerId > value) {
top = index;
}
}
return -1;
}
};
export default Utils;
You need to put hook inside input element. It will work as expected. If you want you can send another default value (in this case it is empty string).
input({
props: {
type: 'text'
},
hook: {
update: (o, n) => n.elm.value = ''
}
}),
#cycle/dom driver should be > 11.0.0 which works with Snabbdom. But if you use earlier version you need:
var Hook = function(){
this.arguments=arguments;
}
Hook.prototype.hook = function(node) {
node.value=this.arguments[0];
}
input({ attributes: {type: 'text'},
'my-hook':new Hook('')
})
I have a to-do list made in HTML, CSS and JavaScript, and I want to show a button only if they are 0 elements unchecked remaining. I think that the code should contain the variable named "numRemaining". I have tried something in JQuery, but it was a total failure.
This is what I have tried:
$(".todo-checkbox").change(function(){
if($(".todo-checkbox:checked").length > 4){
$("#yourButton").show();
}
});
This is my code:
<html>
<head>
<link rel="stylesheet" href="tomo.css">
<title>TOMO</title>
</head>
<body>
<h1>TOMO</h1>
<center>
<div id="todo-app">
<label class="todo-label" for="new-todo">What do you have to do today?</label>
<input type="text" id="new-todo" class="todo-input" placeholder="english homework">
<ul id="todo-list" class="count-this"></ul>
<div id="todo-stats"></div>
</div>
<button onclick="myPrint()">Print</button>
</center>
<script type="text/x-template" id="todo-item-template">
<div class="todo-view">
<input type="checkbox" class="todo-checkbox" {checked}>
<span class="todo-content" tabindex="0">{text}</span>
</div>
<div class="todo-edit">
<input type="text" class="todo-input" value="{text}">
</div>
<a href="#" class="todo-remove" title="Remove this task">
<span class="todo-remove-icon"></span>
</a>
</script>
<script type="text/x-template" id="todo-stats-template">
<span class="todo-count">
<span class="todo-remaining">{numRemaining}</span>
<span class="todo-remaining-label">{remainingLabel}</span> left.
</span>
<a href="#" class="todo-clear">
Clear <span class="todo-done">{numDone}</span>
completed <span class="todo-done-label">{doneLabel}</span>
</a>
</script>
<script src="http://yui.yahooapis.com/3.18.1/build/yui/yui-min.js"></script>
<script>
YUI().use('event-focus', 'json', 'model', 'model-list', 'view', function (Y) {
var TodoAppView, TodoList, TodoModel, TodoView;
TodoModel = Y.TodoModel = Y.Base.create('todoModel', Y.Model, [], {
sync: LocalStorageSync('todo'),
toggleDone: function () {
this.set('done', !this.get('done')).save();
}
}, {
ATTRS: {
done: {value: false},
text: {value: ''}
}
});
TodoList = Y.TodoList = Y.Base.create('todoList', Y.ModelList, [], {
model: TodoModel,
sync: LocalStorageSync('todo'),
done: function () {
return this.filter(function (model) {
return model.get('done');
});
},
remaining: function () {
return this.filter(function (model) {
return !model.get('done');
});
}
});
TodoAppView = Y.TodoAppView = Y.Base.create('todoAppView', Y.View, [], {
events: {
'#new-todo': {keypress: 'createTodo'},
'.todo-clear': {click: 'clearDone'},
'.todo-item': {
mouseover: 'hoverOn',
mouseout : 'hoverOff'
}
},
template: Y.one('#todo-stats-template').getHTML(),
initializer: function () {
var list = this.todoList = new TodoList();
list.after('add', this.add, this);
list.after('reset', this.reset, this);
list.after(['add', 'reset', 'remove', 'todoModel:doneChange'],
this.render, this);
list.load();
},
render: function () {
var todoList = this.todoList,
stats = this.get('container').one('#todo-stats'),
numRemaining, numDone;
if (todoList.isEmpty()) {
stats.empty();
return this;
}
numDone = todoList.done().length;
numRemaining = todoList.remaining().length;
stats.setHTML(Y.Lang.sub(this.template, {
numDone : numDone,
numRemaining : numRemaining,
doneLabel : numDone === 1 ? 'task' : 'tasks',
remainingLabel: numRemaining === 1 ? 'task' : 'tasks'
}));
if (!numDone) {
stats.one('.todo-clear').remove();
}
return this;
},
add: function (e) {
var view = new TodoView({model: e.model});
this.get('container').one('#todo-list').append(
view.render().get('container')
);
},
clearDone: function (e) {
var done = this.todoList.done();
e.preventDefault();
this.todoList.remove(done, {silent: true});
Y.Array.each(done, function (todo) {
todo.destroy({remove: true});
});
this.render();
},
createTodo: function (e) {
var inputNode, value;
if (e.keyCode === 13) { // enter key
inputNode = this.get('inputNode');
value = Y.Lang.trim(inputNode.get('value'));
if (!value) { return; }
this.todoList.create({text: value});
inputNode.set('value', '');
}
},
hoverOff: function (e) {
e.currentTarget.removeClass('todo-hover');
},
hoverOn: function (e) {
e.currentTarget.addClass('todo-hover');
},
reset: function (e) {
var fragment = Y.one(Y.config.doc.createDocumentFragment());
Y.Array.each(e.models, function (model) {
var view = new TodoView({model: model});
fragment.append(view.render().get('container'));
});
this.get('container').one('#todo-list').setHTML(fragment);
}
}, {
ATTRS: {
container: {
valueFn: function () {
return '#todo-app';
}
},
inputNode: {
valueFn: function () {
return Y.one('#new-todo');
}
}
}
});
TodoView = Y.TodoView = Y.Base.create('todoView', Y.View, [], {
containerTemplate: '<li class="todo-item"/>',
events: {
'.todo-checkbox': {click: 'toggleDone'},
'.todo-content': {
click: 'edit',
focus: 'edit'
},
'.todo-input' : {
blur : 'save',
keypress: 'enter'
},
'.todo-remove': {click: 'remove'}
},
template: Y.one('#todo-item-template').getHTML(),
initializer: function () {
var model = this.get('model');
model.after('change', this.render, this);
model.after('destroy', function () {
this.destroy({remove: true});
}, this);
},
render: function () {
var container = this.get('container'),
model = this.get('model'),
done = model.get('done');
container.setHTML(Y.Lang.sub(this.template, {
checked: done ? 'checked' : '',
text : model.getAsHTML('text')
}));
container[done ? 'addClass' : 'removeClass']('todo-done');
this.set('inputNode', container.one('.todo-input'));
return this;
},
edit: function () {
this.get('container').addClass('editing');
this.get('inputNode').focus();
},
enter: function (e) {
if (e.keyCode === 13) {
Y.one('#new-todo').focus();
}
},
remove: function (e) {
e.preventDefault();
this.constructor.superclass.remove.call(this);
this.get('model').destroy({'delete': true});
},
save: function () {
this.get('container').removeClass('editing');
this.get('model').set('text', this.get('inputNode').get('value')).save();
},
toggleDone: function () {
this.get('model').toggleDone();
}
});
function LocalStorageSync(key) {
var localStorage;
if (!key) {
Y.error('No storage key specified.');
}
if (Y.config.win.localStorage) {
localStorage = Y.config.win.localStorage;
}
var data = Y.JSON.parse((localStorage && localStorage.getItem(key)) || '{}');
function destroy(id) {
var modelHash;
if ((modelHash = data[id])) {
delete data[id];
save();
}
return modelHash;
}
function generateId() {
var id = '',
i = 4;
while (i--) {
id += (((1 + Math.random()) * 0x10000) | 0)
.toString(16).substring(1);
}
return id;
}
function get(id) {
return id ? data[id] : Y.Object.values(data);
}
function save() {
localStorage && localStorage.setItem(key, Y.JSON.stringify(data));
}
function set(model) {
var hash = model.toJSON(),
idAttribute = model.idAttribute;
if (!Y.Lang.isValue(hash[idAttribute])) {
hash[idAttribute] = generateId();
}
data[hash[idAttribute]] = hash;
save();
return hash;
}
return function (action, options, callback) {
var isModel = Y.Model && this instanceof Y.Model;
switch (action) {
case 'create': // intentional fallthru
case 'update':
callback(null, set(this));
return;
case 'read':
callback(null, get(isModel && this.get('id')));
return;
case 'delete':
callback(null, destroy(isModel && this.get('id')));
return;
}
};
}
new TodoAppView();
});
</script>
<script>
function myPrint() {
window.print();
}
</script>
</body>
</html>
You can compare the number of checked boxes to the total number of boxes, like this:
var $boxes = $(".todo-checkbox");
$boxes.change(function() {
if ($boxes.filter(':checked').length == $boxes.length) {
$("#yourButton").show();
}
});
This script's purpose is to load the data source into table first,
And then there is a search box to search data.
The dataSource only load at the first time page load,
How to make it reload the data source every 30 seconds, thanks
<TableSorter dataSource={"/welcome/get_winner_list"} config={CONFIG} />
Here's the whole script
/** #jsx React.DOM */
var CONFIG = {
sort: { column: "_id", order: "desc" },
filterText: "",
columns: {
_id: { name: "獎次"},
name: { name: "獎品"},
can_accept_prize_now: { name: "現領"},
staff_name: {name: "姓名"},
staff_id: {name: "工號"},
}
};
var TableSorter = React.createClass({
getInitialState: function() {
return {
items: this.props.initialItems || [],
sort: this.props.config.sort || { column: "", order: "" },
columns: this.props.config.columns,
filterText:this.props.config.filterText
};
},
componentWillMount: function() {
this.loadData(this.props.dataSource);
},
loadData: function(dataSource) {
if (!dataSource) return;
$.get(dataSource).done(function(data) {
console.log("Received data");
this.setState({items: data});
}.bind(this)).fail(function(error, a, b) {
console.log("Error loading JSON");
});
},
handleFilterTextChange: function (event){
this.setState({filterText:event.target.value})
},
editColumnNames: function() {
return Object.keys(this.state.columns);
},
receive_click:function(event){
name_staff=event.target.name.split(',')
dataSource='/take/'+name_staff[0]+'/'+name_staff[1];
$.getJSON(dataSource).done(function() {
console.log("Input success");
}.bind(this)).fail(function(error, a, b) {
console.log("Error :Input Prize");
});
itemsColumn=_.find(this.state.items,function(column){return column['_id']==name_staff[0]});
itemsColumn['taken_at']=true;
this.setState()
},
render: function() {
var rows = [];
var columnNames = this.editColumnNames();
var filters = {};
columnNames.forEach(function(column) {
var filterText = this.state.filterText;
filters[column] = null;
if (filterText.length > 0 ) {
filters[column] = function(x) {
if(x)
return (x.toString().toLowerCase().indexOf(filterText.toLowerCase()) > -1);
};
}
}, this);
var filteredItems = _.filter(this.state.items, function(item) {
return _.some(columnNames, function(c) {
return (!filters[c] || filters[c](item[c]));
}, this);
}, this);
var sortedItems = _.sortBy(filteredItems, this.state.sort.column);
if (this.state.sort.order === "desc") sortedItems.reverse();
var cell = function(x) {
return columnNames.map(function(c) {
if (c == 'taken_at') {
if (x[c])
return <td>
<span className="btn btn-shadow btn-danger" disabled="disabled">已領取</span>
</td>;
else
return <td>
<button name={x['_id']+','+x['staff_id']} className="btn btn-shadow btn-success" onClick={this.receive_click}>未領取</button>
</td>;
}
else if (c == 'can_accept_prize_now') {
if (x[c] )
return <td>
<img src="/images/check.png"></img>
</td>;
else
return <td>
<img src="/images/cross.png"></img>
</td>;
}
else
return <td>{x[c]}</td>;
}, this);
}.bind(this);
sortedItems.forEach(function(item) {
rows.push(
<tr key={item.id}>
{ cell(item) }
</tr>
);
}.bind(this));
var header = columnNames.map(function(c) {
return <th >{this.state.columns[c].name}</th>;
}, this);
return (
<div className="table">
<form>
<fieldset>
<input type="text" name="s" id="s" placeholder="搜尋方式:部分工號、部分姓名、部分獎次,皆可查詢。 Eg: 林 or 726 "
value={this.state.value} onChange={this.handleFilterTextChange}/>
</fieldset>
</form>
<p/>
<table cellSpacing="0" className="table table-striped table-advance table-hover prizes">
<thead>
<tr>
{ header }
</tr>
</thead>
<tbody>
{ rows }
</tbody>
</table>
</div>
);
}
});
var QueryString = function () {
// This function is anonymous, is executed immediately and
// the return value is assigned to QueryString!
var query_string = {};
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
// If first entry with this name
if (typeof query_string[pair[0]] === "undefined") {
query_string[pair[0]] = pair[1];
// If second entry with this name
} else if (typeof query_string[pair[0]] === "string") {
var arr = [ query_string[pair[0]], pair[1] ];
query_string[pair[0]] = arr;
// If third or later entry with this name
} else {
query_string[pair[0]].push(pair[1]);
}
}
return query_string;
} ();
var App = React.createClass({
render: function() {
return (
<div>
<TableSorter dataSource={"/welcome/get_winner_list"} config={CONFIG} />
</div>
);
}
});
$( document ).ready(function() {
console.log( "ready!" );
if(document.getElementById("searchWinner")){
React.render(<App />, document.getElementById("searchWinner"));
}
});
Update
I got the Uncaught TypeError: Cannot read property 'interval' of null
by the following code
getInitialState: function() {
return {
interval: 5,
items: this.props.initialItems || [],
sort: this.props.config.sort || { column: "", order: "" },
columns: this.props.config.columns,
filterText:this.props.config.filterText
};
},
componentDidMount: function() {
setInterval(function() {
this.setState({
interval: this.state.interval + 1
});
}.bind(this), 1000);
},
componentWillMount: function() {
this.loadData(this.props.dataSource);
},
var App = React.createClass({
render: function() {
return (
<div>
<TableSorter key={this.state.interval} dataSource={"/welcome/get_winner_list"} config={CONFIG} />
</div>
);
}
});
I suppose TableSorter is external component, so I suggest to force component to re-render using key property from parent component. Something like
componentDidMount: function() {
setInterval(function() {
this.setState({
interval: this.state.interval + 1
});
}.bind(this), 1000);
},
render: function() {
return <TableSorter key={this.state.interval} dataSource={"/welcome/get_winner_list"} config={CONFIG} />
}
Minus is that will reset any state inside TableSorter (paging, selected rows) after interval.
i can use this script:
setInterval(function() {
alert("alert every 3 second");
}, 3000);
EXAMPLE