javascript - 按名称或 ID 排序的资产
问题描述
我有一个集合列表(在我的屏幕左侧),只要单击集合(屏幕右侧)就会显示它们的资产。我现在正在尝试添加基于选择标签的资产排序功能(请参阅渲染)。默认情况下,资产应按名称排序,但下拉菜单允许用户在“按 id 排序”和“按名称排序”之间切换。我在 handleAssetsClick() 中创建资产。我遇到的问题是我无法在不重新单击集合并因此激活 handleAssetsClick() 的情况下更新资产。handleAssetsClick 很重要,因为它可以选择哪些资产是每个集合的一部分。
关于如何解决这个问题的任何建议?
import React from 'react';
import './App.css';
import {collections} from "./data.js"
import {assets} from "./data.js"
import {FaStar} from "react-icons/fa"
class App extends React.Component {
constructor() {
super()
this.state = {
collectionsarr: collections,
assetsarr: assets,
clickedassets: []
}
}
handleAssetsClick(id){
const clickedassetsdata = this.state.assetsarr.filter(asset => asset.collectionId === id)
this.setState({
clickedassets: clickedassetsdata
})
}
makeMaster(idclick){
const themasteridnr = this.state.clickedassets.filter(masterpot => masterpot.id === idclick)[0].id
const newcollections = this.state.collectionsarr.slice()
const index = this.state.clickedassets.filter(masterpot => masterpot.id === idclick)[0].collectionId - 1
newcollections[index].masterAssetId = themasteridnr
this.setState({
...this.state,
collectionsarr: newcollections
})
}
getAssetPath(masterAssetId){
const asset = this.state.assetsarr.find(x => x.id === masterAssetId)
return asset ? require(`./${asset.path}`) : ''
}
getMasterId(assetnr){
let idresult = this.state.collectionsarr.find(collection => collection.masterAssetId === assetnr)
if(typeof idresult === "undefined"){
return -1
} else if (typeof idresult !== "undefined"){
return idresult.masterAssetId
}
}
render(){
return (
<div className="App">
<h1>Coding challenge</h1>
<label>Sort assets by:</label>
<select name="sorting">
<option value="sortbyname">NAME</option>
<option value="sortbyid">ID</option>
</select>
<div className="left">
{this.state.collectionsarr.map(element =>
<div key={element.id}>
<p onClick={()=>this.handleAssetsClick(element.id)}>{element.name}</p>
<img src={this.getAssetPath(element.masterAssetId)} alt="pic"/>
<br></br>
<br></br>
</div>
)}
</div>
<div className="right">
{this.state.clickedassets.map(asset =>
<div key={asset.id}>
<img src={require(`./${asset.path}`)} alt="pic"/>
<p>{asset.name}</p>
<p>{asset.id}</p>
{asset.id !== this.getMasterId(asset.id) && <button onClick={() => this.makeMaster(asset.id)}>Make master!</button> }
{asset.id === this.getMasterId(asset.id) && <FaStar />}
<br></br>
<br></br>
</div>
)}
</div>
</div>
)
}
}
export default App
数据.js
const collections = [
{
id: 1,
name: "The Simpsons",
masterAssetId: 13,
tags: {
name: "Cartoon",
subTag: {
name: "Simpsons family",
subTag: {
name: "2014",
},
},
},
},
{
id: 2,
name: "Super heroes",
masterAssetId: 24,
tags: {
name: "DC Super heroes",
subTag: {
name: "2014",
},
},
},
{
id: 3,
name: "Toy story",
masterAssetId: 31,
tags: {
name: "Disney",
subTag: {
name: "Pixar",
subTag: {
name: "Original movie",
subTag: {
name: "2010",
},
},
},
},
},
{
id: 4,
name: "Ninjago",
masterAssetId: 42,
tags: {
name: "Ninja",
subTag: {
name: "Secret Ninja Force",
subTag: {
name: "2017",
},
},
},
},
];
const assets = [
{
id: 11,
name: "Homer Simpson",
path: "Homer.jpg",
collectionId: 1,
},
{
id: 12,
name: "Lisa Simpson",
path: "Lisa.jpg",
collectionId: 1,
},
{
id: 13,
name: "Bart Simpson",
path: "Bart.jpg",
collectionId: 1,
},
{
id: 14,
name: "Marge Simpson",
path: "Marge.jpg",
collectionId: 1,
},
{
id: 15,
name: "Grampa Simpson",
path: "Grampa.jpg",
collectionId: 1,
},
{
id: 16,
name: "Maggie Simpson",
path: "Maggie.jpg",
collectionId: 1,
},
{
id: 21,
name: "Green Lantern",
path: "Green lantern.jpg",
collectionId: 2,
},
{
id: 22,
name: "Flash",
path: "Flash.jpg",
collectionId: 2,
},
{
id: 23,
name: "Batman",
path: "Batman.jpg",
collectionId: 2,
},
{
id: 24,
name: "Superman",
path: "Superman.jpg",
collectionId: 2,
},
{
id: 31,
name: "Buzz Lightyear",
path: "Buzz.jpg",
collectionId: 3,
},
{
id: 32,
name: "Alien",
path: "Alien.jpg",
collectionId: 3,
},
{
id: 41,
name: "Spinjitzu training Nya",
path: "Nya.jpg",
collectionId: 4,
},
{
id: 42,
name: "Master Wu",
path: "Wu.jpg",
collectionId: 4,
},
{
id: 43,
name: "Lloyd",
path: "Lloyd.jpg",
collectionId: 4,
},
];
export {collections}
export {assets}
解决方案
将onChange
处理程序添加到将排序设置为状态的选择。如果状态中已经有一个“clickedassets”数组,您可以相应地更新它。除了内容之外,您可能还需要跟踪单击的 id,以便您可以重新运行您正在执行的任何过滤等。
// define whatever sort functions you need
const sort = {
'name': (a, b) => localeCompare(a.name, b.name), // or whatever
'id': (a, b) => localeCompare(a.id, b.id),
}
// save sort selection in state and re-trigger handleAssetsClick
onSortChange({target: {value}}) {
const {selectedId} = this.state;
this.setState({ sort: value });
if (selectedId) {
this.handleAssetsClick(selectedId);
}
}
// might want to rename this since it may be called without a click
handleAssetsClick(id){
const {
assetsarr,
sort = 'id' // get selected sort, default to 'id'
} = this.state;
const clickedassetsdata = assetsarr
.filter(asset => asset.collectionId === id)
.sort(sort[sort]); // sort according to state.sort value
this.setState({
selectedId: id,
clickedassets: clickedassetsdata
});
}
<select name="sorting" onChange={onSortChange}>
{
// render select options based on available sort functions
Object.keys(sort).map(sortOption => (
<option key={sortOption}>{sortOption}</option>
))
}
</select>
推荐阅读
- node.js - 在 NodeJs 中上传和读取 excel 文件
- python - 按python中的另一个list.index对压缩列表进行排序
- javascript - 从 Firebase 获取用户个人资料信息时出现问题
- r - 拆分和重组数据帧时如何保留单个观察的行名?
- javascript - Angular - 无法获取父组件数据
- android - Nativescript,无法在设备上进行更改。错误是:无法读取 null 的属性“startsWith”
- javascript - 在与按钮相同的 div 块中获取跨度的内部文本
- reactjs - 如何在单个反应 js 组件中导出两个模块?
- c - C中的哈希宏定义
- python - 从 excel 创建 Python 字典