我试图通过打开/关闭用于创建那些项目的技能组件来控制GalleryItem组件的可见性。我想要: 如果没有技能切换,则显示全部 如果切换了一项或多项技能,则仅显示使用该技能的GalleryItems
所选技能存储在Portfolio组件的state.portfolioTypes中-可以按预期工作。
我只是不知道如何从我的Skill组件的点击处理程序中调用每个GalleryItem组件上的updateDisplay方法。
如果有人可以帮助我,那我就飞了!谢谢。
我尝试将GalleryItem组件推到处于父状态的数组中,以便在切换技能时可以遍历该数组,但是尽管在将数组登录到控制台时看到了组件对象,但它们并没有在用户界面中呈现-而是呈现数字13-24(不知道为什么...)
resumeData.skills如下:
skills: ["Branding", "Design", "UX", "Marketing", "Print", "Javascript", "HTML", "Grunt", "JQuery", "LessCSS", "Sketch", "Photoshop", "Illustrator", "Bootstrap"]
传递给GalleryItem类的项目如下:
{
imagePath: "images/portfolio/monster.png",
name: "Monster.com",
description: "Web design, UI Development and Art Direction",
modalImagePath: "images/portfolio/lrg/monster.png",
modalName: "Web design, UI Development and Art Direction",
modalDescription: "Working for one of the internet's biggest brands, I developed UI for internal incubator projects, components of the global web application and helped with the full UI redesign of the job seeker experience.",
modalCategories: ["Branding", "Design", "UX", "Photoshop", "Illustrator"],
url: "http://www.monster.com"
}
我的投资组合类,其中包含技能类和GalleryItem类: (我删除了一些与此问题无关的代码)
import React, { Component } from 'react';
export default class Portfolio extends Component {
constructor(props){
super(props);
this.state = {
portfolioTypes: [],
galleryItems: []
}
this.togglePortfolioItems = this.togglePortfolioItems.bind(this);
}
togglePortfolioItems(item){
//render only portfolio items with selected tags
console.log("togglePortfolioItems", item);
let portfolioTypes = this.state.portfolioTypes;
if(!item.isToggleOn){
portfolioTypes.push(item.type);
}else{
portfolioTypes.splice(portfolioTypes.indexOf(item.type), 1);
}
this.setState({portfolioTypes: portfolioTypes});
console.log(this.state.portfolioTypes, portfolioTypes);
}
render() {
let resumeData = this.props.resumeData;
let togglePortfolioItems = this.togglePortfolioItems;
let portfolioTypes = this.state.portfolioTypes;
let galleryItems = this.state.galleryItems;
return (
<React.Fragment>
<section id="portfolio">
<div className="row">
<div className="twelve columns collapsed">
<h1>Check Out Some of My Works.</h1>
<div className="skillToggles">
{resumeData.skills.map((item,index) => (
<Skill
skillName={item}
togglePortfolioItems={togglePortfolioItems}
galleryItems={galleryItems}
/>
))}
</div>
{/* portfolio-wrapper */}
<div id="portfolio-wrapper" className="bgrid-quarters s-bgrid-thirds cf">
{resumeData.portfolio.map((item,index) => (
galleryItems.push(<GalleryItem
item={item}
index={index}
portfolioTypes={portfolioTypes}
/>)
))}
</div> {/* portfolio-wrapper end */}
</div> {/* twelve columns end */}
</div> {/* row End */}
</section> {/* Portfolio Section End*/}
</React.Fragment>
);
this.setState({galleryItems: galleryItems});
}
}
class Skill extends Component {
constructor(props) {
super(props);
this.state = {
isToggleOn: false,
type: props.skillName.toLowerCase()
};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
this.props.togglePortfolioItems(this.state);
let galleryItems = this.props.galleryItems;
//loop through all galleryItems and set the display of each
galleryItems.map(galleryItem =>(
console.log(galleryItem);
//I would like to fire updateDisplay on galleryItem here
));
}
render() {
let skillName = this.props.skillName;
let skillNameId = skillName.toLowerCase();
return (
<React.Fragment>
<a href="" className={"skill "+(this.state.isToggleOn ? 'on' : 'off')} onClick={this.handleClick}>
{skillName}
</a> {/* Skill Section End*/}
</React.Fragment>
);
}
}
class GalleryItem extends Component{
constructor(props) {
super(props);
let portfolioTypes = this.props.portfolioTypes;
var displayed = true;
this.state = {
displayed: displayed
};
}
updateDisplay(){
let portfolioTypes = this.state.portfolioTypes;
let displayed = false;
if(portfolioTypes.length === 0){
displayed = true;
}else{
for(var x=0; x<portfolioTypes.length; x++){
let cat = portfolioTypes[x];
if(portfolioTypes.indexOf(cat) > -1){
displayed = true;
}
};
}
this.setState({displayed: displayed});
}
render() {
let item = this.props.item;
let index = this.props.index;
return (
<React.Fragment>
<div className={"columns portfolio-item "+(this.state.displayed ? "" : "hide ")+item.modalCategories.sort().join(" ").toLowerCase()}>
<div className="item-wrap">
<a href={"#modal-0"+index} title={item.name}>
<img alt src={item.imagePath} />
<div className="overlay">
<div className="portfolio-item-meta">
<h5>{item.name}</h5>
<p>{item.description}</p>
</div>
</div>
<div className="link-icon"><i className="icon-plus" /></div>
</a>
</div>
</div>
</React.Fragment>
);
}
}
切换技能时,我希望图库更新为仅显示使用所选技能的GalleryItem。
也许您也可以建议对我的方法进行改进,因为可能有更好/更容易/更健壮的方法来实现这一目标。
答案 0 :(得分:1)
updateDisplay(){
let portfolioTypes = this.props.portfolioTypes;
let displayed = false;
if(portfolioTypes.length === 0){
displayed = true;
}else{
for(var x=0; x<portfolioTypes.length; x++){
let cat = portfolioTypes[x];
if(portfolioTypes.indexOf(cat) > -1){
displayed = true;
}
};
}
return displayed;
}
var displayed = this.updateDisplay()
答案 1 :(得分:0)
import React, { Component } from 'react';
export default class Portfolio extends Component {
constructor(props){
super(props);
this.state = {
portfolioTypes: []
}
this.togglePortfolioItems = this.togglePortfolioItems.bind(this);
}
togglePortfolioItems(item){
//render only portfolio items with selected tags
console.log("togglePortfolioItems", item);
let portfolioTypes = this.state.portfolioTypes;
if(!item.isToggleOn){
portfolioTypes.push(item.type);
}else{
portfolioTypes.splice(portfolioTypes.indexOf(item.type), 1);
}
this.setState({portfolioTypes: portfolioTypes});
console.log(this.state.portfolioTypes, portfolioTypes);
}
render() {
let resumeData = this.props.resumeData;
let togglePortfolioItems = this.togglePortfolioItems;
let portfolioTypes = this.state.portfolioTypes;
return (
<React.Fragment>
<section id="portfolio">
<div className="row">
<div className="twelve columns collapsed">
<h1>Check Out Some of My Works.</h1>
<div className="skillToggles">
{resumeData.skills.map((item,index) => (
<Skill
skillName={item}
key={index}
togglePortfolioItems={togglePortfolioItems}
/>
))}
</div>
{/* portfolio-wrapper */}
<div id="portfolio-wrapper" className="bgrid-quarters s-bgrid-thirds cf">
{resumeData.portfolio.map((item,index) => (
<GalleryItem
item={item}
index={index}
key={index}
portfolioTypes={portfolioTypes}
/>
))}
</div> {/* portfolio-wrapper end */}
</div> {/* twelve columns end */}
</div> {/* row End */}
</section> {/* Portfolio Section End*/}
</React.Fragment>
);
}
}
class Skill extends Component {
constructor(props) {
super(props);
this.state = {
isToggleOn: false,
type: props.skillName
};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
e.preventDefault();
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
this.props.togglePortfolioItems(this.state);
}
render() {
let skillName = this.props.skillName;
return (
<React.Fragment>
<a href="#" className={"skill "+(this.state.isToggleOn ? 'on' : 'off')} onClick={this.handleClick}>
{skillName}
</a> {/* Skill Section End*/}
</React.Fragment>
);
}
}
class GalleryItem extends Component{
constructor(props) {
super(props);
let portfolioTypes = this.props.portfolioTypes;
}
updateDisplay(){
console.log("updateDisplay");
let portfolioTypes = this.props.portfolioTypes;
let item = this.props.item;
let displayed = false;
if(portfolioTypes.length === 0){
displayed = true;
}else{
for(var x=0; x<portfolioTypes.length; x++){
let cat = portfolioTypes[x];
if(item.modalCategories.indexOf(cat) > -1){
displayed = true;
}
};
}
return displayed;
}
render() {
let item = this.props.item;
let index = this.props.index;
var displayed = this.updateDisplay();
return (
<React.Fragment>
<div className={"columns portfolio-item "+(displayed ? "" : "hide ")+item.modalCategories.sort().join(" ")}>
<div className="item-wrap">
<a href={"#modal-0"+index} title={item.name}>
<img alt="Gallery Image" src={item.imagePath} />
<div className="overlay">
<div className="portfolio-item-meta">
<h5>{item.name}</h5>
<p>{item.description}</p>
</div>
</div>
<div className="link-icon"><i className="icon-plus" /></div>
</a>
</div>
</div>
</React.Fragment>
);
}
}