如何通过只调用一次compute函数在AngularJs视图中多次显示相同的计算值



在我看来,我想多次显示计算属性,如果我多次执行{{ctrl.Compute()}},那么计算函数被多次调用。

我已经创建了这个plunkr演示来简单地回答我的问题http://plnkr.co/edit/TcMcJUipLKk94dthnivU

控制器

app.controller('MainController',function(){
  var ctrl= this;
  var list = [];
  ctrl.count = function(){
    console.log('Invoked');
    return list.length
  }

  ctrl.add = function(){
    list.push(1)
  }
});
<<p> 视图/strong>
 <body ng-controller="MainController as ctrl">
    <button ng-click="ctrl.add()">Add</button>
    <br>
    List Size: {{ctrl.count()}} <br>
    List Size: {{ctrl.count()}} <br>
    List Size: {{ctrl.count()}} <br>
    List Size: {{ctrl.count()}} <br>
  </body>

在视图中,你可以看到我调用{{ctrl.count()}}四次,这意味着计算发生了四次。我怎么能只做一次计算,并显示一个值多次?


请不要建议,例如,将控制器的数组部分做成ctrl.list,然后考虑使用{{ctrl.list.length}}。这个想法可能适用于这个例子,但不适用于需要复杂计算的地方

可以这样写:

var savedCount = ctrl.count();
ctrl.count = function(){
    console.log('Invoked');
    return list.length
}
$scope.$watch("list", function() {savedCount = ctrl.count()});

您可以使用一种称为记忆的技术。

在计算中,记忆是一种主要使用的优化技术通过存储昂贵的结果来加速计算机程序函数调用并返回相同输入时缓存的结果再次发生。

您可以使用lodash之类的流行库,也可以自己编写(不鼓励)。

你可以在这里找到一个类似于你的用例的使用示例,讨论计算繁重的过滤器,类似于使用绑定到计算函数。

检查活塞。在作用域上使用一个新变量,如:

ctrl.counter = ctrl.count();
$scope.$watch(function () {
  return list;
}, function () {
  ctrl.counter = ctrl.count();
}, true);

在HTML上:

List Size: {{ctrl.counter}} <br>
List Size: {{ctrl.counter}} <br>
List Size: {{ctrl.counter}} <br>
List Size: {{ctrl.counter}} <br>

$watch函数观察每一次值list的变化,并每次调用回调函数

你可以通过使用bindHtmlUnsafe指令来做到这一点,而且你的计数对象应该是一个$scope对象,然后它是可能的。请复制粘贴我的答案。

    app.controller('MainController',function($scope){
     $scope.list = [];  
      $scope.context = '<br/> List Size: ' +
       $scope.list.length + ' <br/>List Size: ' + $scope.list.length + 
      '<br/>List Size: ' + $scope.list.length + ' <br/> List Size: ' + 
        $scope.list.length + ' <br/>';
     $scope.add = function () {
        $scope.list.push(1);
        $scope.context = '<br/> List Size: ' + $scope.list.length + ' <br/>List  
        Size: ' + $scope.list.length + '<br/>List Size: ' + $scope.list.length + 
       '<br/> List Size: ' + $scope.list.length + ' <br/>';
    }    
  });
app.directive('bindHtmlUnsafe', function ($compile) {
    return function ($scope, $element, $attrs) {
        var compile = function (newHTML) { // Create re-useable compile function
            newHTML = $compile(newHTML)($scope); // Compile html
            $element.html('').append(newHTML); // Clear and append it
        };
        var htmlName = $attrs.bindHtmlUnsafe; // Get the name of the variable 
        // Where the HTML is stored
        $scope.$watch(htmlName, function (newHTML) { // Watch for changes to 
            // the HTML
            if (!newHTML) return;
            compile(newHTML);   // Compile it
        });
    };
});
然后

<body ng-controller="MainController">
      <button ng-click="add()">Add</button>
            <div bind-html-unsafe="context"></div>
  </body>

这是你的问题的一个可选的解决方案:)

请参阅Plunker如何解决这个问题与你的角版本代码。

最新更新