- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个非常大的动态表单,它是根据通过 AJAX 收集的数据呈现的。
有一个包含表格的表单。该表包含一个标题,然后包含一系列行(由状态数据确定)。每行都有一系列单元格(也由状态数据确定)。每个单元格都包含一个复选框。
我的问题是在哪里维护大量复选框的状态。最初我的方法是让复选框控制组件,每个单元格保持其复选框的状态。
我还尝试将选择框的状态实现为父表单组件本身的状态。
前一种方法的问题是,当我提交表单时,我没有表单级别的状态,因为它被埋在单元格后代中。我能以某种方式得到这个状态吗? findDomNode
似乎只是当前组件,而不是级联组件。此外,标题单元格具有复选框,每当检查列中的所有行时都会检查这些复选框,此解决方案不允许我获得更新该信息的信息。
后一种方法的问题是,当我对一个复选框进行更改时,状态更改会导致表单组件重新渲染,进而导致整个表格重新渲染(或至少调用它的渲染方法)。这非常耗时,并且对于一个大表(通常可以是 100x50)来说,重新渲染需要非常不友好的时间。
归根结底,选中复选框的影响应该非常小。复选框本身应该更新,并且如果列的完全选择状态已更改,则可能需要更新列标题才能选中/取消选中。就是这样。
我已经删除了很多代码,但这基本上就是我正在处理的内容。了解表中的单元格复选框正在跟踪应将哪些标签应用于图像可能会有所帮助。表头单元格跟踪哪些标记(从图像名称中提取的文本)映射到哪些标签。当这种情况发生变化时,该列必须重新渲染(我还没有解决的另一个问题,我怀疑如果不完全重新渲染所有内容,这将再次变得困难)。
var AutoTagForm = React.createClass({
getInitialState: function() {
return {data: {
tags: [],
images: {},
tokens: [],
tokenTagMap: {}
}
};
},
componentDidMount: function() {
$.ajax({
url: this.props.url,
type: "POST",
data: { imageIds: this.props.images },
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
onSubmit: function(e) {
e.preventDefault()
// Submit the updates to the server
},
cellCheckedChange: function(image, tag) {
// If the image has the tag, add it. Otherwise remove it
var tagIndex = image.checkedTags.indexOf(tag)
// TODO Perhaps it is safer to find the image object in this.state.data?
if (tagIndex === -1) {
image.checkedTags.push(tag);
} else {
image.checkedTags.splice(tagIndex, 1);
}
this.setState({
data: this.state.data
})
},
render: function() {
var images = this.state.data.images;
var tokenTagMap = this.state.data.tokenTagMap;
var cellCheckedChange = this.cellCheckedChange;
var rowNodes = Object.keys(images).map(function(key){
if (images.hasOwnProperty(key)) {
var image = images[key];
return (
<AutoTagImageRow key={image.id}
image={image}
tokenTagMap={tokenTagMap}
cellCheckedChange={cellCheckedChange} />
);
}
});
return (
<form ref="form" onSubmit={this.onSubmit} id="updateAllForm" className={'autotagForm'}>
<div>
<input type="submit"
value="Apply" />
</div>
<div>
<table>
<thead>
<AutoTagHeaderRow tags={this.state.data.tags}
tokens={this.state.data.tokens}
tokenTagMap={this.state.data.tokenTagMap} />
</thead>
<tbody>
{rowNodes}
</tbody>
</table>
</div>
</form>
);
}
});
var AutoTagImageRow = React.createClass({
render: function() {
var image = this.props.image;
var tokenTagMap = this.props.tokenTagMap;
var cellCheckedChange = this.props.cellCheckedChange;
var cellNodes = Object.keys(tokenTagMap).map(function(token){
if (tokenTagMap.hasOwnProperty(token)) {
return (
<AutoTagImageRowCell image={image}
token={token}
tokenTagMap={tokenTagMap}
cellCheckedChange={cellCheckedChange} />
);
}
});
return (
<tr>
{cellNodes}
<td>{image.clientPath}</td>
</tr>
);
}
});
var AutoTagImageRowCell = React.createClass({
isTagged: function() {
var image = this.props.image;
var token = this.props.token;
var tokenTagMap = this.props.tokenTagMap;
var tag = tokenTagMap[token];
return (image.tags.indexOf(tag) !== -1);
},
isChecked: function() {
var image = this.props.image;
var token = this.props.token;
var tokenTagMap = this.props.tokenTagMap;
var tag = tokenTagMap[token];
return (image.checkedTags.indexOf(tag) !== -1);
},
handleCheckedChange: function() {
var image = this.props.image;
var token = this.props.token;
var tokenTagMap = this.props.tokenTagMap;
var tag = tokenTagMap[token];
this.props.cellCheckedChange(image, tag);
},
render: function() {
var className = '';
if (this.isTagged()) {
className = 'success';
}
return (
<td className={className}>
<input type="checkbox"
checked={this.isChecked()}
onChange={this.handleCheckedChange} />
</td>
);
}
});
我是 React 新手,可能会做出一些糟糕的设计决策!这与我之前使用简单的 javascript 做事的方式非常不同,我热衷于遵循 React 哲学,但我觉得它几乎立即就出错了,因为这是我尝试做的第一件事过了教程。
最佳答案
好的。经过一些额外的研究,我发现了这个问题的一个很好的解决方案。
关键是能够判断哪些组件需要重新渲染。这是我之前考虑过的事情,但是确定图像行是否需要重新渲染所需的状态所需的比较几乎与重新渲染本身一样密集。
输入Immutable.js 。我将我的 javascript 对象转换为不可变的映射,并将我的数组转换为不可变的集合。像这样:
for (var key in data.images) {
// data.images[key] = Immutable.fromJS(data.images[key]);
data.images[key] = Immutable.fromJS(
data.images[key], function (key, value) {
var isIndexed = Immutable.Iterable.isIndexed(value);
return isIndexed ? value.toSet() : value.toMap();
}
);
}
我还没有转换整个数据
,因为其中还有其他数据位尚未更新为使用不可变,但这是可能的。
然后,当我从一个复选框处理 onChange 时,我会在表单级别实现它,如下所示:
cellCheckedChange: function(imageId, tagId) {
var images = this.state.data.images;
var image = images[imageId];
// If the image has the tag, add it. Otherwise remove it
var checked = image.hasIn(['checkedTags', tagId]);
images[imageId] = image.update('checkedTags', function(value) {
return checked ? value.delete(tagId): value.add(tagId);
});
this.setState({
data: this.state.data
});
},
因此,对不可变对象(immutable对象)的更新会导致创建新对象。这将对不可变的状态结构产生向上的级联效应,因为对子级的任何更改都需要一个新的父级。不过,任何未直接更新或通过向上级联更新的状态仍然是相同的对象,这很重要,因为您可以独立地推理这些对象。
最后,我更新了图像行组件,仅在图像是新对象时更新(如果图像或任何后代已更新,则将是新对象):
var AutoTagImageRow = React.createClass({
render: function() {
...
},
// Only update an image row that has had a modified state
shouldComponentUpdate: function(nextProps, nextState) {
return nextProps.image !== this.props.image;
}
...
});
因此,当发生更新时,会发生更多的工作来操作 javascript 状态,但作为返回,我可以很容易地推断出哪些内容已更改,哪些内容未更改!
正如我上面提到的,不可变对象(immutable对象)的嵌套层次结构中未替换的任何部分都是相同的对象,因此可以将它们与旧结构的子级进行比较,以查看它们是否已使用结果进行更新但他们没有。这是一个独立的示例。
var Immutable = require('immutable');
var input = {
'1': 'aaa',
'2': [1,2,3,4]
};
var x = Immutable.fromJS(
input, function (key, value) {
var isIndexed = Immutable.Iterable.isIndexed(value);
return isIndexed ? value.toSet() : value.toMap();
}
);
// Get another reference to x
var y = x;
// Update the array stored in '2'
x = x.update('2', function(v) {
return v.add(7);
});
// object '1' remains the same JS object
console.log(x.get('1') === y.get('1')); //True
// object '2' is a new JS object
console.log(x.get('2') === y.get('2')); //False
// Overall 'x' is a new JS object
console.log(x === y); //False
关于javascript - React js 重新渲染表单中的大量组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32958634/
在我的 OpenGL 程序中,我按顺序执行以下操作: // Drawing filled polyhedrons // Drawing points using GL_POINTS // Displa
我想传递一个包含原始页面的局部变量,这个变量只包含一个带有值的符号。 当我使用此代码时,它运行良好,可以在部分中访问 origin 变量: render :partial => "products",
为什么这个 HTML/脚本(来自“JavaScript Ninja 的 secret ”)不渲染? http://jsfiddle.net/BCL54/
我想在阅读完 View 后返回到特定的网页位置(跳转到页内 anchor )。换句话说,在 views.py 中,我想做类似的事情: context={'form':my_form} return r
我有一个包含单条折线的 PathGeometry,并以固定的间隔向该线添加一个新点(以绘制波形)。使用 Perforator 工具时,我可以看到每次向直线添加一个点时,WPF 都会将整个 PathGe
尝试了解如何消除或最小化网站上不同 JavaScript 库的渲染延迟。 例如,如果我想加载来自许多社交网络的“即时”关注按钮,它们似乎会相互阻止渲染,并且您会收到令人不快的弹出窗口。 (func
我有以 xyz 点格式表示 3D 表面(即地震断层平面)的数据。我想创建这些表面的 3D 表示。我使用 rgl 和 akima 取得了一些成功,但是它无法真正处理可能会自行折叠或在同一 x,y 点具有
我正在用 Libgdx 编写一个小游戏。 我有一个 Render[OpenGL] 线程,它不断对所有对象调用 render() 和一个更新线程不断对所有对象调用 update(double delta
我有一个 .Rmd 文件包含: ```{r, echo=FALSE, message=FALSE, results='asis'} library(xtable) print(xtable(group
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
请不要评判我,我只是在学习 Swift。 最近我安装了 MetalPetal 框架,并按照说明操作: https://github.com/MetalPetal/MetalPetal#example-
如果您尝试渲染 Canvas 宽度和高度之外的图像,计算机是否仍会尝试渲染它并使用资源来尝试渲染它?我只是想找出在尝试渲染图像之前检查图像是否在 Canvas 内是否更好。 最佳答案 我相信它仍然在无
我在 safari 中渲染时遇到问题。 在 firefox、chrome 和 IE 上。如下图所示: input.searchbox{-webkit-border-radius:10px;-moz-b
我正在尝试通过远程桌面在 Windows7 下运行我在 RHEL7 服务器中制作的 java 程序。 服务器中的所有java程序都无法通过远程桌面呈现。如果我在服务器位置访问服务器本身,它们看起来没问
我正处于一个新项目的设计阶段,该项目将采用数据集并将其加载到文档中,然后围绕模板呈现文档。呈现的文件可以是 CSV 数据集、PDF 营销信函、电子邮件……很多东西。数据不会是数学方程式,我只是在寻找一
有没有办法在不同的 div 下渲染 React 组件的子组件? ... ... ... ... ...
使用以下代码: import numpy as np from plotly.offline import iplot, init_notebook_mode import plotly.graph_
截至最近, meteor 的所有文档都指出 onRendered是一种在模板完成渲染时获取回调的新方法。和 rendered只是为了向后兼容。 但是,这似乎对我不起作用。 onRendered永远不会
所以在我的基本模板中,我有:{% render "EcsCrmBundle:Module:checkClock" %} 然后我创建了 ModuleController.php ... getDoctr
我正在使用 vue-mathjax 来编译我的 vue 项目中的数学方程。它正在编译第一个括号 () 之间的文本。我想防止编译括号内的字符串。在文档中我发现,对于$符号,如果我们想逃避编译,我们需要使
我是一名优秀的程序员,十分优秀!