如何为Hyperledger Angular Composer自动生成的前端添加交易按钮?
Got it, let's walk through how to add transaction buttons to your Angular Composer-generated frontend. I've tackled this exact scenario before, so here's a step-by-step breakdown that should get you sorted:
First, figure out where you want the transaction button to live—this is usually on an asset detail page, asset list page, or participant profile page. For example, if you want to add a transfer transaction for MyAsset, head to the corresponding component files: src/app/my-asset/my-asset-detail.component.ts (for the detail view) or my-asset-list.component.ts (for bulk actions).
Your generated code already uses the BusinessNetworkConnection service—we'll leverage this to pull transaction metadata from your Hyperledger Composer business network. Update your component class like this:
import { BusinessNetworkConnection, TransactionDeclaration } from 'composer-common'; export class MyAssetDetailComponent implements OnInit { transactionDeclarations: TransactionDeclaration[]; selectedAsset: any; // This should already exist if you're on the detail page constructor(private businessNetworkConnection: BusinessNetworkConnection) { } ngOnInit() { // Assume you've already fetched the selectedAsset here this.businessNetworkConnection.getBusinessNetwork().then(bn => { const modelManager = bn.getModelManager(); // Filter to get only the transaction you want (e.g., 'TransferAsset') this.transactionDeclarations = modelManager.getAllTransactionDeclarations() .filter(td => td.getName() === 'TransferAsset'); }); } }
Open the component's HTML template (e.g., my-asset-detail.component.html) and add the button, binding it to a click handler. You can loop through multiple transactions if needed:
<div class="asset-details-container"> <h3>Asset Details: {{selectedAsset.$identifier}}</h3> <!-- Existing asset detail fields go here --> <!-- Transaction Button --> <button *ngFor="let tx of transactionDeclarations" class="btn btn-action" (click)="launchTransaction(tx.getName())"> Execute {{tx.getName()}} </button> </div>
Back in the component's TypeScript file, add the launchTransaction method to handle building, populating, and submitting the transaction to the blockchain:
launchTransaction(transactionName: string) { // Build a transaction instance from the definition const transaction = this.businessNetworkConnection.buildTransaction(transactionName); // Populate transaction fields (adjust based on your transaction's schema) transaction.asset = this.selectedAsset.$identifier; // Link to the current asset transaction.newOwner = 'resource:org.example.MyParticipant#user123'; // Replace with actual participant ID, or let users input it // Submit the transaction this.businessNetworkConnection.submitTransaction(transaction) .then(() => { alert('Transaction completed successfully!'); this.refreshAssetData(); // Refresh to show updated asset state }) .catch(err => { console.error('Transaction failed:', err); alert(`Oops, something went wrong: ${err.message}`); }); } // Helper method to refresh the asset after transaction refreshAssetData() { this.businessNetworkConnection.getAssetRegistry('org.example.MyAsset') .then(registry => registry.get(this.selectedAsset.$identifier)) .then(updatedAsset => this.selectedAsset = updatedAsset); }
If your transaction requires user input (like selecting a new owner), create a modal form to collect data. Using Angular Material's MatDialog makes this straightforward:
// Import dialog components import { MatDialog } from '@angular/material/dialog'; import { TransactionInputFormComponent } from '../transaction-input-form/transaction-input-form.component'; // Inject MatDialog in the constructor constructor( private businessNetworkConnection: BusinessNetworkConnection, private dialog: MatDialog ) { } launchTransaction(transactionName: string) { const dialogRef = this.dialog.open(TransactionInputFormComponent, { data: { assetId: this.selectedAsset.$identifier } }); dialogRef.afterClosed().subscribe(formData => { if (formData) { const transaction = this.businessNetworkConnection.buildTransaction(transactionName); transaction.asset = this.selectedAsset.$identifier; transaction.newOwner = `resource:org.example.MyParticipant#${formData.ownerId}`; this.businessNetworkConnection.submitTransaction(transaction) .then(() => { alert('Transaction submitted!'); this.refreshAssetData(); }) .catch(err => console.error(err)); } }); }
Then create TransactionInputFormComponent with a simple input field to collect the owner ID.
Don't forget to verify that your participant identity has permission to execute the transaction! Check your business network's ACL file (.acl) and add a rule if needed:
rule AllowAssetTransfer { description: "Allow participants to transfer assets" participant: "org.example.MyParticipant" operation: ALL resource: "org.example.TransferAsset" action: ALLOW }
内容的提问来源于stack exchange,提问作者Vcoss

