首页 > 解决方案 > 如何在 Angular 中实现不同的视图?

问题描述

我正在尝试为区块链实现模拟。区块链由一个带有矿工的网络组成。在我的示例中,我有 10 个矿工。这些矿工中的每一个都有一个候选块,他们将交易池中的交易放入其中。交易来自网络并被放入交易池。示例:如果矿工 1 将交易 A 放入他的候选区块,交易 A 应该仍然在矿工 2-10 的交易池中可用。它仍然可用,因为该交易尚未被挖掘。如果矿工 1 的区块被挖出,那么交易 A 应该从每个交易池中删除。

问题是,如何为每个节点实现不同的视图。如何在节点之间切换并保持事务池附加到每个节点?

我在我的项目中使用网格布局。一个网格显示具有所有节点的网络。一个网格显示每个节点的块。一个网格显示存储在池中的全局事务。但是每个节点都应该在本地存储交易,这意味着如果节点 1 接受一个交易,那么该交易应该仍然存在于节点 2 和其他节点中。

矿工-View.ts:

export class MinerViewComponent implements OnDestroy, OnInit {
          transaction: Transaction;
          displayedColumns: string[] = ['sender', 'recipient', 'amount', 'fee'];
          dataSource = new MatTableDataSource<Transaction>(ELEMENT_DATA);
          temp: Transaction[] = [];
          blockNumber = 1;
          previousHash = '00000000000000000000000000000000';
          blockHash: string = this.generateFirstHash();
          blockHashList: string[] = [];

      panelOpenState = false;

      message: any;
      subscription: Subscription;

      constructor(private ref: ChangeDetectorRef, private emitTransactionService: EmitTransactionService,
                  private messageService: MessageService) {
        this.subscription = this.messageService.getMessage().subscribe(message => {
          this.message = message;
          this.sendBlockToBC();
          this.clearBlock();
        });
      }

      ngOnDestroy() {
        this.subscription.unsubscribe();
      }

      ngOnInit() {
        this.emitTransactionService.row$.subscribe(transaction => {
            this.transaction = transaction;
            this.temp = this.dataSource.data.slice();
            this.temp.push(this.transaction);
            this.dataSource.data = this.temp;
            this.ref.detectChanges();
          }
        );
        this.temp = this.dataSource.data.slice();
        this.temp.pop();
        this.dataSource.data = this.temp;
        this.ref.detectChanges();
      }

      /** This method clears the current block of the miner (transactions only), when a new block has been added to the
       * blockchain. **/
      clearBlock() {
        this.ref.detectChanges();
        console.log('Transactions none.');
      }

      sendMessage(): void {
        this.messageService.sendMessage2('Message from miner view component to block-card component!');
      }

      /** This method puts the block from the active miner in the blockchain (when he got the proof-of-...). **/
      sendBlockToBC() {
        const block = new Block(this.blockNumber, this.temp, this.previousHash, this.blockHash);
        this.emitTransactionService.emitBlock(block);
        setTimeout(() => {
            console.log(block);
            this.temp = null;
            this.dataSource = undefined; // to empty the table in the miner view component
            this.dataSource = new MatTableDataSource<Transaction>(ELEMENT_DATA); // create new datasource to fill the table,
            // since the old one gives an error
            this.generateBlockHash();
            this.raiseBlockNumber();
            this.sendMessage();
          },
          100);

      }

交易池组件.ts:

export class TransactionPoolComponent implements OnInit {
          displayedColumns: string[] = ['select', 'sender', 'recipient', 'amount', 'fee'];
          dataSource = new MatTableDataSource<Transaction>(ELEMENT_DATA);
          selection = new SelectionModel<Transaction>(true, []);
          transaction: Transaction;
          temp: Transaction[];

      constructor(private ref: ChangeDetectorRef, private emitTransactionService: EmitTransactionService) {
      }

      /** This method gets the selected row as input. The selected row then gets deleted from the transaction
       * pool and appears in the block of the miner. **/
      putTXInBlock(row) {
        this.temp = this.dataSource.data.slice();
        for (let i = 0; i < this.temp.length; i++) {
          if (JSON.stringify(row) === JSON.stringify(this.temp[i]) ) {
            this.temp.splice(i, 1);
            break;
          }
        }
        this.dataSource.data = this.temp;
        this.ref.detectChanges();
        this.emitTransactionService.emitRow(row);
      }

      ngOnInit() {
          this.emitTransactionService.transaction$.subscribe(transaction => {
              this.transaction = transaction;
              this.temp = this.dataSource.data.slice();
              this.temp.push(this.transaction);
              this.dataSource.data = this.temp;
              this.ref.detectChanges();
            }
          );
          this.temp = this.dataSource.data.slice();
          this.temp.pop();
          this.dataSource.data = this.temp;
          this.ref.detectChanges();
      }
    } 

目前我刚刚为节点 1 实现了它。我想我必须改变我的代码的整个概念,或者它可以通过一个小的改变来工作吗?我希望它适用于所有节点。

问题:目前我不知道如何分别管理所有 10 个节点的数据源。因为每个节点都应该有自己的数据源以及所有全局事务。另一件事是如何让所有 10 个节点进入界面。我的想法是实现一个< >按钮,在这里我可以在 1-10 之间切换。但是最简单的方法是什么?对于每个节点的视图,我的意思是每个节点都有自己的事务池,所有全局事务都被放入其中。然后每个节点可以将这些事务放入自己的块中。但是这些交易不会被其他节点删除。我的问题与用户体验和数据模型有关。

如果您需要更多信息或不清楚的地方,请告诉我。我会尝试改进这个问题。

具有 10 个节点的网络:

在此处输入图像描述

上面的块应该显示来自节点块的信息。较低的块应该显示带有交易的池,在这种情况下属于节点 1。

在此处输入图像描述

标签: htmlangulartypescriptview

解决方案


推荐阅读