1

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.

2
  • 1
    I would make a model (a factory in angular) and keep all your logic in there for the resulting data you want. You can do the calculation once by calling a function on the model. Commented Nov 2, 2015 at 19:08
  • What @ajmajmajma means is use a service/factory to create an API that you would expose as a SINGLETON. So all you would do at that point is inject the service/factory into w.e needed. Commented Nov 2, 2015 at 20:45

1 Answer 1

1

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();
}]
Sign up to request clarification or add additional context in comments.

2 Comments

Hi, thanks for the great replies. I tried it to implement with service but it failed somehow.
Ah sorry can't edit first comment anymore. I made it. Thanks for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.