Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: call function from the view

Tags:

angularjs

Hi I have the next problem:

In my view I call a function prepareDynamicData(itemMenu);

<div ng-repeat="itemMenu in menuDetailsData.categories" class="headDetails fontH2">
            <div style="display: none">{{prepareDynamicData(itemMenu)}}</div>
            <a href="#" ng-show="dynamicData.expand">{{itemMenu.name}}</a>
            <div ng-repeat="cat in dynamicData.data">
                <p>{{cat.name}}</p>
                <div class="articles">
                    <div ng-repeat="art in cat.items" class="article">
                        <div class="price">
                            <div></div>
                            <span><i>₪</i>{{art.price}}</span>
                        </div>
                        <div class="artDescr">
                            <span class="fontTitle">{{art.title}}</span>
                            <p class="fontDetails">{{art.description}}</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>

I know that top loop repeting only 2 times (verified that), but function prepareDynamicData(itemMenu) calling 4 times, don't know why!? Here is my controller:

function MenuItemCtrl($scope, $routeParams, $http, $location, sharedData) {
if (sharedData.getMenuDetails() == null) {
    $location.path('/menu');
    return;
}
else {
    $scope.menu = sharedData.getMenu();
    $scope.menuDetailsData = sharedData.getMenuDetailsData($routeParams.itemId);
}

$scope.dynamicData = {
    data : new Array(),
    expand : false
};

$scope.prepareDynamicData = function (itemMenu) {
    if (itemMenu.items != null) {
        $scope.dynamicData.data[0] = itemMenu;
        $scope.dynamicData.expand = false;
    }
    else {
        $scope.dynamicData.data = itemMenu.categories;
        $scope.dynamicData.expand = true;
    }
}

}

Can you help me clarify why it's happening! thanks

like image 941
Simcha Avatar asked Apr 21 '13 05:04

Simcha


1 Answers

AngularJS uses dirty tracking to make sure the view stays up to date. That means AngularJS will evaluate the values of your view's bindings until they stabilize; thus, it will do this at least twice per binding any time that binding's associated scope updates. (For example, if a specific item internal to the loop changed, it would likely run an additional two times.) This is why care must be taken to ensure that functions bound in the view have no side effects and run quickly.

In general, moving data preparation tasks into code that runs when the controller loads, or into a service that is called from the controller, is a good practice--view related code should rarely have side effects! However, if you must/really want to call a function like this from the view, simply keep track of whether or not the function has already been called for the given item.

Here is a bit of additional reading on dirty tracking in Angular if you're interested.

like image 59
Michelle Tilley Avatar answered Oct 17 '22 17:10

Michelle Tilley