html - 如何在angularjs中刷新html Canvas 指令

标签 html angularjs

我有一个页面,当单击加号按钮时,计数框应该增加一行以及投票。例如,当我有 51 票时,计数框应该显示 10 个框和 1 行。在我的网页中,添加选票工作正常,51 票增加到 52,但计数框没有增加。我给它放了一个 $watch 和 $observe 但它没有修复。到目前为止我所做的是:

var tb = angular.module("tb", []);
tb.controller("tallyboxController", function ($scope) {
	'use strict';
    $scope.addVote = function(no){
    $scope.presidents.votes+=1;
    console.log($scope.presidents.votes);
    }

    
    $scope.addLine = function(){
    	//alert("Tina");
    	$scope.hello = "tina";
    	console.log($scope.hello);
    	};

        $scope.label = {
      table:{
        cName:"Candidate's Name",
        cVote:'Vote',
        cTB:'Tally Boxes',
        cNV:'No of votes',
        period:'.'
      },
    };
    
    $scope.presidents = [
      {
        no:'1',
        name:'Jeoanna Lingh',
        votes:51,
      }
    ];
    
    $scope.candidates = [
      $scope.presidents,
      $scope.vicepresidents
    ];

    console.log($scope.presidents.votes);


    	

});


var tb = angular.module('tb');

tb.directive('drawing', function(){
  return {
    restrict: 'A',
    link: function(scope, element,attrs){
      var votes = scope.value.votes;
      var ctx = element[0].getContext('2d');
      var remainder = 0;
      var oneBox = 0;

        if(votes > 4){
          if(remainder = votes%5){
            oneBox =  (votes-remainder)/5 ; 
          }
          drawOneBox()
          }else{
          remainder = votes;
        }

        console.log(votes);

        ctx.beginPath()

        function drawOneBox(){
          var i;
            for (i=0;i<oneBox;i++){
              ctx.moveTo(5+i*25, 5);
              ctx.lineTo(25+i*25, 5);

              ctx.moveTo(5+i*25, 5);
              ctx.lineTo(5+i*25, 25);

              ctx.moveTo(25+i*25, 5);
              ctx.lineTo(25+i*25, 25);

              ctx.moveTo(5+i*25, 5);
              ctx.lineTo(25+i*25, 25);

              ctx.moveTo(25+i*25, 25);
              ctx.lineTo(5+i*25, 25);
              ctx.strokeStyle = "Red";
              ctx.stroke();
            }
         
              if(remainder==1){
                ctx.moveTo(5+i*25, 5);
                ctx.lineTo(5+i*25, 25);
                ctx.strokeStyle = "Red";
                ctx.stroke();
              }

              if(remainder==2){
                ctx.moveTo(5+i*25, 5);
                ctx.lineTo(25+i*25, 5);

                ctx.moveTo(5+i*25, 5);
                ctx.lineTo(5+i*25, 25);
                ctx.strokeStyle = "Red";
                ctx.stroke();
              }

              if(remainder==3){
                ctx.moveTo(5+i*25, 5);
                ctx.lineTo(25+i*25, 5);

                ctx.moveTo(5+i*25, 5);
                ctx.lineTo(5+i*25, 25);

                ctx.moveTo(25+i*25, 5);
                ctx.lineTo(25+i*25, 25);

                ctx.strokeStyle = "Red";
                ctx.stroke();
              }

              if(remainder==4){
                ctx.moveTo(5+i*25, 5);
                ctx.lineTo(25+i*25, 5);

                ctx.moveTo(5+i*25, 5);
                ctx.lineTo(5+i*25, 25);

                ctx.moveTo(25+i*25, 5);
                ctx.lineTo(25+i*25, 25);

                ctx.moveTo(25+i*25, 25);
                ctx.lineTo(5+i*25, 25);

                ctx.strokeStyle = "Red";
                ctx.stroke();
              }          
           };             
        } // end 
      };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html data-ng-app="tb">
<head lang="en">
	<meta charset="utf-8">
	<title>Tally Boxes</title>
</head>
<body data-ng-controller="tallyboxController" data-ng-init="init()">
  <div id="container">
   </div>
  <div class="container-table">
    <table border="1" width="100%">
        <thead>
            <tr>
                <td>{{label.table.cName}}</td>
                <td colspan="2">{{label.table.cVote}}</td>
                <td>{{label.table.cTB}}</td>
                <td>{{label.table.cNV}}</td>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="(key,value) in candidates[0]">
                <td>{{value.no}} {{label.table.period}} {{value.name}}</td>
              <td><button ng-click="addVote(key)">+</button></td>
              <td><button ng-click="minus(key)">-</button></td>
              
                <td><canvas width="500" height="26" id="{{value.no}}" drawing></canvas></td>
                <td>{{value.votes}}</td>           
            </tr>
        </tbody>
</table>
</div>

  <script src="angular.min.js"></script>  
  <script src="tallyboxController.js"></script>
  <script src="tallyboxDirective.js"></script>


</body>
</html>

任何帮助将不胜感激。谢谢!

最佳答案

它需要几个关键的修复,这是我所做的:

  • 向指令添加了一个属性 candidate 和一个 isolate 作用域,因此我们在 isolate 作用域变量和 Controller 作用域变量之间有双重绑定(bind)(这样我们就不必使用 scope.$parent...)
  • 将线性代码移动到一个函数中,以便在需要时可以再次调用它(链接器只执行一次)
  • 添加了一个 votes 观察器,它将使用我在上一步中提到的函数重新渲染 Canvas 。
  • 在渲染开始时添加了一个干净的 Canvas 调用(否则它会一遍又一遍地在同一个 Canvas 上绘制)
  • 添加缺失的 oneBox = votes/5; 以防没有余数
  • 添加了减少投票功能(当然对于修复不是很重要,但更容易测试)

这是工作版本:

var tb = angular.module("tb", []);
tb.controller("tallyboxController", function($scope) {
  'use strict';
  $scope.addVote = function(no) {
    $scope.presidents[no].votes += 1;
  }
  
  $scope.minus = function(no) {
    $scope.presidents[no].votes -= 1;
  }


  $scope.addLine = function() {
    //alert("Tina");
    $scope.hello = "tina";
    console.log($scope.hello);
  };

  $scope.label = {
    table: {
      cName: "Candidate's Name",
      cVote: 'Vote',
      cTB: 'Tally Boxes',
      cNV: 'No of votes',
      period: '.'
    },
  };

  $scope.presidents = [{
    no: '1',
    name: 'Jeoanna Lingh',
    votes: 52,
  }];

  $scope.candidates = [
    $scope.presidents,
    $scope.vicepresidents
  ];

});


var tb = angular.module('tb');

tb.directive('drawing', function() {
  return {
    restrict: 'A',
    scope: {
      candidate: '='
    },
    link: function(scope, element, attrs) {

        var colors = ['Red', 'Green', 'Blue', 'Yellow'];

        scope.$watch("candidate.votes", function(newValue, oldValue) {
          console.log('rendering', newValue);
          render();
        });

        function render() {
          var votes = scope.candidate.votes;
          var ctx = element[0].getContext('2d');
          var remainder = 0;
          var oneBox = 0;
          
          // clear canvas (needed for subtracting votes)
          // and is a good practice anyway
          element[0].width = element[0].width;

          if (votes > 4) {
            if (remainder = votes % 5) {
              oneBox = (votes - remainder) / 5;
            }
            else {
              oneBox = votes / 5;
            }
          } else {
            remainder = votes;
          }
          
          drawOneBox();          

          function drawOneBox() {
            ;
            for (var i = 0; i < oneBox; i++) {
              
              var color = colors[Math.floor(i/5)];

              ctx.beginPath();
              ctx.moveTo(5 + i * 25, 5);
              ctx.lineTo(25 + i * 25, 5);

              ctx.moveTo(5 + i * 25, 5);
              ctx.lineTo(5 + i * 25, 25);

              ctx.moveTo(25 + i * 25, 5);
              ctx.lineTo(25 + i * 25, 25);

              ctx.moveTo(5 + i * 25, 5);
              ctx.lineTo(25 + i * 25, 25);

              ctx.moveTo(25 + i * 25, 25);
              ctx.lineTo(5 + i * 25, 25);
              ctx.strokeStyle = color;
              ctx.stroke();
            }
            
            // recheck the color
            color = colors[Math.floor(oneBox/5)];

            if (remainder == 1) {
              ctx.beginPath();
              ctx.moveTo(5 + i * 25, 5);
              ctx.lineTo(5 + i * 25, 25);
              ctx.strokeStyle = color;
              ctx.stroke();
            }

            if (remainder == 2) {
              ctx.beginPath();
              ctx.moveTo(5 + i * 25, 5);
              ctx.lineTo(25 + i * 25, 5);

              ctx.moveTo(5 + i * 25, 5);
              ctx.lineTo(5 + i * 25, 25);
              ctx.strokeStyle = color;
              ctx.stroke();
            }

            if (remainder == 3) {
              ctx.beginPath();
              ctx.moveTo(5 + i * 25, 5);
              ctx.lineTo(25 + i * 25, 5);

              ctx.moveTo(5 + i * 25, 5);
              ctx.lineTo(5 + i * 25, 25);

              ctx.moveTo(25 + i * 25, 5);
              ctx.lineTo(25 + i * 25, 25);

              ctx.strokeStyle = color;
              ctx.stroke();
            }

            if (remainder == 4) {
              ctx.beginPath();
              ctx.moveTo(5 + i * 25, 5);
              ctx.lineTo(25 + i * 25, 5);

              ctx.moveTo(5 + i * 25, 5);
              ctx.lineTo(5 + i * 25, 25);

              ctx.moveTo(25 + i * 25, 5);
              ctx.lineTo(25 + i * 25, 25);

              ctx.moveTo(25 + i * 25, 25);
              ctx.lineTo(5 + i * 25, 25);

              ctx.strokeStyle = color;
              ctx.stroke();
            }
          };
        }
        render();
      } // end 
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html data-ng-app="tb">

<head lang="en">
  <meta charset="utf-8">
  <title>Tally Boxes</title>
</head>

<body data-ng-controller="tallyboxController" data-ng-init="init()">
  <div id="container">
  </div>
  <div class="container-table">
    <table border="1" width="100%">
      <thead>
        <tr>
          <td>{{label.table.cName}}</td>
          <td colspan="2">{{label.table.cVote}}</td>
          <td>{{label.table.cTB}}</td>
          <td>{{label.table.cNV}}</td>
        </tr>
      </thead>
      <tbody>
        <tr ng-repeat="(key,value) in candidates[0]">
          <td>{{value.no}} {{label.table.period}} {{value.name}}</td>
          <td>
            <button ng-click="addVote(key)">+</button>
          </td>
          <td>
            <button ng-click="minus(key)">-</button>
          </td>

          <td>
            <canvas width="500" height="26" id="{{value.no}}" candidate="value" drawing></canvas>
          </td>
          <td>{{value.votes}}</td>
        </tr>
      </tbody>
    </table>
  </div>

</body>

</html>

关于html - 如何在angularjs中刷新html Canvas 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27890074/

相关文章:

AngularJS - 从范围加载 HTML 实体作为货币符号

javascript - 驯服客户端 ORM 中的 hasMany/belongsToOne 循环引用

jquery - fancybox 有 html 问题

html - 谁可以给我解释一下这个? (HTML CSS)

javascript - 当我升级到 1.11 时,Jquery Animate 表现异常

javascript - 支持最低分辨率打开网站

angularjs - 如何在 Angular UI Bootstrap 中查看模态是否打开

html - 使用 Bootstrap 以响应方式添加图像和其他元素

javascript - 在 ng-repeat 中使用 AngularJS 从一种状态到另一种状态进行动画处理

javascript - 如何以 Angular 验证日期格式