AngularJs scope reference with directives

Jon Watkins

I'm trying to write a very simple 3 star scoring system in Angular, however I have run into issues with directive scopes when using a reference to an item in an array.

For testing purposes my markup looks like this:

<div id="ref">
    <span>Reference to item 1: </span>
    <item-score ng-model="selected.score"></item-score>
</div>


<div ng-repeat="item in items track by $index">
    <div class="row">
        <span>{{item.name}}:</span>
        <item-score ng-model="item.score"></item-score>
        <item-score ng-model="item.score"></item-score>
    </div>
</div>

And my JavaScript has been simplified but does the same thing:

var App = angular.module('testApp', []);

App.controller('MainCtrl', ['$scope', function ($scope) {
    $scope.items = [
        { id: 1, score: 1, name: 'Item 1' },
        { id: 2, score: 2, name: 'Item 2' },
        { id: 3, score: 1, name: 'Item 3' }
    ];
    $scope.selected = $scope.items[1];
}]);

App.directive('itemScore', function () {
    return {
        restrict: 'E',
        require: '?ngModel',
        replace: true,
        template: '<div class="score"><i class="fa fa-star" ng-click="set($index+1)"' +
                  ' ng-repeat="star in stars track by $index" ' +
                  'ng-class="{ yellow: star === true }"></i></div>',
        link: function (scope, elm, attrs, ctrl) {
            var num = 5;

            scope.stars = new Array(num);

            scope.set = function (score) {
                if (ctrl.$viewValue === score) { score--; }
                ctrl.$setViewValue(score);
            };

            function setStars () {
                for (var i = 0; i < num; i += 1) {
                    scope.stars[i] = ((i+1) <= ctrl.$viewValue ? true : false);
                }
            }

            ctrl.$render = function () {
                setStars();
            };
        }
    }
});

I have created a plunker http://plnkr.co/edit/QIXc1Nw68q7Zt1gsoa2P?p=preview

when clicking in the rows each score box will update correctly, but when you click the stars above the the rows (uses a reference to the 2nd item in the array) it will update both directives in the row, but will not update itself.

I need the directive to work with a reference as the item is passed into another directive to use inside a modal window (my app has the same behaviour as the plunker).

Any help would be appreciated thanks in advance.

bmleite

When you click in the score boxes inside each row, both are update correctly because both directives are watching the same property. So when one of the directives changes the number of starts the other one is notified of that change and forces a render. Since both directives are inside the same ng-repeat scope, both score boxes are re-rendered.

Try to remove one of the directives from the row inside the ng-repeat and you will notice it will no longer update correctly.

One way to fix it is to call ctrl.$render() after setting the view value. Like this:

scope.set = function (score) {
  if (ctrl.$viewValue === score) { score--; }
    ctrl.$setViewValue(score);
    ctrl.$render();
};

The other option is to define a ng-modelreference in the scope and update it directly.

require : 'ngModel', 
scope: {
  ngModel: '=?'
}

And then:

scope.set = function (score) {
  scope.ngModel = score;
};

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

AngularJS : directives and scope

From Dev

angularjs inheriting scope in nested directives

From Dev

Isolate scope in Angularjs custom directives - "="

From Dev

AngularJs attributes vs scope in directives

From Dev

AngularJS : Nested Directives and Scope Inheritance

From Dev

AngularJs attributes vs scope in directives

From Dev

AngularJS directives - Isolated Scope and Inherited Scope

From Dev

angularjs - isolate scope between multiple different directives

From Dev

Why are my AngularJS directives sharing scope?

From Dev

AngularJS Directives - Can Isolated Scope Attributes be required?

From Dev

AngularJs: multiple directives asking for isolated scope on

From Dev

AngularJS directives - isolated scope special binding characters

From Dev

Angularjs isolated scope for directives without own template

From Dev

Using "this" instead of "scope" with AngularJS controllers and directives

From Dev

angularjs - Multiple directives asking for new / isolated scope

From Dev

AngularJS directive - template from $scope with other directives

From Dev

AngularJS directives - isolated scope special binding characters

From Dev

AngularJS Directives - Can Isolated Scope Attributes be required?

From Dev

AngularJS : Scope is not shared between nested transcluded directives

From Dev

angularjs - isolate scope between multiple different directives

From Dev

Scope in directives

From Dev

Scope in directives

From Dev

require:ngModel vs. scope: { ngModel: '=' } on AngularJS Directives

From Dev

AngularJS directives with HTML5 drag and drop -- issue with scope object

From Dev

AngularJS 1.4 directives: scope, two way binding and bindToController

From Dev

AngularJS directive with callback in scope prevents other directives from working

From Dev

problems with the scope variable over communication between the directives in angularjs

From Dev

AngularJS directives accessing the same scope object - avoid overwrite

From Dev

Confuse about the AngularJS scope when multiple directives share same element

Related Related

  1. 1

    AngularJS : directives and scope

  2. 2

    angularjs inheriting scope in nested directives

  3. 3

    Isolate scope in Angularjs custom directives - "="

  4. 4

    AngularJs attributes vs scope in directives

  5. 5

    AngularJS : Nested Directives and Scope Inheritance

  6. 6

    AngularJs attributes vs scope in directives

  7. 7

    AngularJS directives - Isolated Scope and Inherited Scope

  8. 8

    angularjs - isolate scope between multiple different directives

  9. 9

    Why are my AngularJS directives sharing scope?

  10. 10

    AngularJS Directives - Can Isolated Scope Attributes be required?

  11. 11

    AngularJs: multiple directives asking for isolated scope on

  12. 12

    AngularJS directives - isolated scope special binding characters

  13. 13

    Angularjs isolated scope for directives without own template

  14. 14

    Using "this" instead of "scope" with AngularJS controllers and directives

  15. 15

    angularjs - Multiple directives asking for new / isolated scope

  16. 16

    AngularJS directive - template from $scope with other directives

  17. 17

    AngularJS directives - isolated scope special binding characters

  18. 18

    AngularJS Directives - Can Isolated Scope Attributes be required?

  19. 19

    AngularJS : Scope is not shared between nested transcluded directives

  20. 20

    angularjs - isolate scope between multiple different directives

  21. 21

    Scope in directives

  22. 22

    Scope in directives

  23. 23

    require:ngModel vs. scope: { ngModel: '=' } on AngularJS Directives

  24. 24

    AngularJS directives with HTML5 drag and drop -- issue with scope object

  25. 25

    AngularJS 1.4 directives: scope, two way binding and bindToController

  26. 26

    AngularJS directive with callback in scope prevents other directives from working

  27. 27

    problems with the scope variable over communication between the directives in angularjs

  28. 28

    AngularJS directives accessing the same scope object - avoid overwrite

  29. 29

    Confuse about the AngularJS scope when multiple directives share same element

HotTag

Archive