I am currently in the process of developing a web application for a board game and have opted to utilize the Aurelia JavaScript framework for the front-end. While I am new to Aurelia, I encountered an obstacle when attempting to create a new instance of a custom component with just the click of a button. To provide further clarity on my issue, let me illustrate what I aim to achieve using an example. The configuration for the game project I want to execute is as shown:
To shed more light on the problem I am facing, I have prepared a basic example. This challenge mainly roots from my unfamiliarity with Aurelia rather than any other factor. In this simplistic demonstration, I have the main app.js viewmodel and app.html view that Aurelia recognizes as the primary viewmodel and view respectively. They are structured as follows:
app.js
import { Card } from './card';
export class App {
cards = [];
newCard() {
this.cards.push(new Card());
}
}
app.html
<template>
<require from="./card"></require>
<button click.delegate="newCard()">New Card</button>
<div>
<li repeat.for="card of cards">
<compose view-model="card"></compose>
</li>
</div>
</template>
Moreover, there exists a card component that simply represents a playing card. Below are its viewmodel and view:
card.js
export class Card {
cardValues = ['2','3','4','5','6','7','8','9','10',
'J','Q','K','A'];
cardSuits = ['Diamonds', 'Clubs', 'Hearts', 'Spades'];
value;
suit;
activate() {
this.value = this.pickRandomItem(this.cardValues);
this.suit = this.pickRandomItem(this.cardSuits);
}
pickRandomItem(data) {
let index = Math.floor(Math.random() * (data.length -1));
return data[index];
}
}
card.html
<template>
<div style="border: 2px solid black;
display: inline-block;
margin-top: 10px;">
<h3>Value: ${value}</h3>
<h4>Suit: ${suit}</h4>
</div>
</template>
At present, I can generate new cards dynamically by clicking the button in the app view, triggering the instantiation of a new Card object in the app viewmodel's button click event handler. However, my concern lies in manually instantiating the Card objects from the app viewmodel. It seems like there should be a way to instruct Aurelia to create a new Card object, but I have not grasped how to achieve that yet. Therefore, my query is: Is there a more efficient method to dynamically produce custom components without the need to manually instantiate them as I am currently doing?
I find this approach incorrect because with the current structure, the constructor for a Card object is called twice instead of once. Additionally, if the Card class necessitates injected dependencies, I would have to pass those into the new Card objects manually, which feels cumbersome.
Thank you tremendously for your assistance!
You can access the minimal functional repository through this link on GitHub