You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular5中对象在同级兄弟组件间迁移及moves属性递减问题

Hey there! Let's work through fixing this component migration issue you're facing. The core problem here is that sibling components can't directly share state or update each other's data—we need to lift the shared state up to a parent component to handle the cross-component moves and moves counter updates.

Here's a step-by-step solution tailored to your setup:

First, let's assume you have a parent component that wraps both your Starters and Bench components. We'll move all shared state (player arrays and the moves counter) into this parent, then pass down data and callback functions to the siblings.

1. Parent Component (e.g., TeamManager.tsx)

This component will manage the source of truth for your players and move counter, and define the logic to transfer players between components:

import { useState } from 'react';
import Starters from './starters';
import Bench from './bench';
// Import your player type from your service file
import { Player } from './path-to-your-service-file';

// Replace with your actual initial data fetch logic
const getInitialStarters = () => [/* your starter players */];
const getInitialBench = () => [/* your bench players */];

const TeamManager = () => {
  const [starters, setStarters] = useState<Player[]>(getInitialStarters());
  const [bench, setBench] = useState<Player[]>(getInitialBench());
  const [moves, setMoves] = useState<number>(/* your initial moves value */);

  // Move a player from Starters to Bench
  const handleMoveToBench = (selectedPlayer: Player) => {
    if (moves <= 0) return; // Block moves when no attempts left

    // Update arrays immutably (critical for React state updates)
    setStarters(prev => prev.filter(player => player.id !== selectedPlayer.id));
    setBench(prev => [...prev, selectedPlayer]);
    // Decrement moves counter
    setMoves(prev => prev - 1);
  };

  // Move a player from Bench to Starters
  const handleMoveToStarters = (selectedPlayer: Player) => {
    if (moves <= 0) return;

    setBench(prev => prev.filter(player => player.id !== selectedPlayer.id));
    setStarters(prev => [...prev, selectedPlayer]);
    setMoves(prev => prev - 1);
  };

  return (
    <div className="team-container">
      <Starters 
        players={starters} 
        movesLeft={moves} 
        onMoveToBench={handleMoveToBench} 
      />
      <Bench 
        players={bench} 
        movesLeft={moves} 
        onMoveToStarters={handleMoveToStarters} 
      />
    </div>
  );
};

export default TeamManager;

2. Updated starters.ts Component

This component receives its data and move callback as props, and renders the move button for each player:

import { Player } from './path-to-your-service-file';

type StartersProps = {
  players: Player[];
  movesLeft: number;
  onMoveToBench: (player: Player) => void;
};

const Starters = ({ players, movesLeft, onMoveToBench }: StartersProps) => {
  const handleMove = (player: Player) => {
    if (movesLeft <= 0) {
      alert('No moves remaining!');
      return;
    }
    onMoveToBench(player);
  };

  return (
    <div>
      <h2>Starters</h2>
      <p>Remaining Moves: {movesLeft}</p>
      <ul>
        {players.map(player => (
          <li key={player.id}>
            {player.name} {/* Replace with your player display logic */}
            <button 
              onClick={() => handleMove(player)}
              disabled={movesLeft <= 0}
            >
              Move to Bench
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Starters;

3. Updated bench.ts Component

Mirror the starters component logic for moving players back to starters:

import { Player } from './path-to-your-service-file';

type BenchProps = {
  players: Player[];
  movesLeft: number;
  onMoveToStarters: (player: Player) => void;
};

const Bench = ({ players, movesLeft, onMoveToStarters }: BenchProps) => {
  const handleMove = (player: Player) => {
    if (movesLeft <= 0) {
      alert('No moves remaining!');
      return;
    }
    onMoveToStarters(player);
  };

  return (
    <div>
      <h2>Bench</h2>
      <p>Remaining Moves: {movesLeft}</p>
      <ul>
        {players.map(player => (
          <li key={player.id}>
            {player.name}
            <button 
              onClick={() => handleMove(player)}
              disabled={movesLeft <= 0}
            >
              Move to Starters
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Bench;

Key Fixes & Explanations:

  • State Lifting: By moving the player arrays and moves counter to the parent, we ensure both sibling components always have access to the latest, synchronized data.
  • Immutable State Updates: We use filter and the spread operator ([...prev]) to create new arrays instead of modifying the original ones. This lets React detect state changes and re-render components correctly.
  • Controlled Moves: We check if moves > 0 before allowing any transfers, and disable buttons when no moves are left to prevent invalid actions.

内容的提问来源于stack exchange,提问作者LDB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:21:03