Robin
Robin

Reputation: 63

Angular repeat scope calculations

Hi i'm building a form doing a lot of calculations, such as summarizing keys in objects

[
    { bar: 5, .. },
    { bar: 6, .. },
    ...
]

I use this expression in currently 35 places in my HTML. Sometimes connected to further calculations and with different keys

<div>
    {{ sumKeys('bar') + foobar }}
</div>

The function i use is declared as

app.controller('someCtrl', function($scope){
    $scope.sumKeys= function(key){
        return (calculated sum);
    }
}

My problem is, that if i write a single letter into any input field the sum function is called about 400 times. I know there is a rule, that calls the function if a scope is changed up to 10 times, but isn't there a more efficient way?

Can i output the result without changing the scope? Or force this calculation just to be done once? I know the results do not change any involved scope. So the results should be the same after 2 iterations. I also implemented the function as a filter with same results.

Upvotes: 1

Views: 38

Answers (1)

Yeysides
Yeysides

Reputation: 1292

What you're looking for is a SINGLETON service. You can make one in angular like this: (one of my real examples)

 angular.module('ocFileUpload', [])
        .service('ocFileUpload', ['$http', '$rootScope', function ($http, $rootScope) {

            // Will house our files
            this.files = [];

            // This fn appends files to our array
            this.addFile = function(files){
                for (var i = 0; i < files.length; i++){
                    this.files.push(files[i]);
                }
            };

            this.getFileDetails = function(ele){
                    // push files into an array.
                    for (var i = 0; i < ele.files.length; i++) {
                        this.files.push(ele.files[i])
                    }
            };

            this.removeFile = function(fileToRemove){
                var indexOfFile = this.files.indexOf(fileToRemove);
                this.files.splice(indexOfFile, 1);
            };

            this.clearFiles = function(){
                this.files = [];
            };

            // Return files array
            this.getFiles = function(){
                return this.files;
            };
        }]);

Then just simply use it in your controller/directive:

.controller(['ocFileUpload', function(ocFileUpload){
  var ref = ocFileUpload.getFiles();
}]

Upvotes: 1

Related Questions