Wonko
Wonko

Reputation: 176

AngularJS : watch/observe attribute change

i want to update the attribute of an element via it's id and have the element react to this change.

I tried to create a plunkr to reflect my situation, but there i can't seem to get even ng-click to work.

However, what i want to do is call a function that does the following

var cell = angular.element(document.querySelector('#' + cellName));
cell.attr('card-id', id);

Which seems to work, according to the values i can read out again directly after these lines.

the receiving element looks like this:

deckbuilderApp.directive('card', function() {
    return {
        restrict: 'E',
        replace: true,
        templateUrl: 'tpl/deckCard.tpl.html',
        scope: {
            cardId: '=cardId'
        },
        link: function(scope, element, attrs) {
            attrs.$observe('cardId', function(newId) {
                console.log('observe cardId: new Value: ' + newId);
                console.log('observe cardId: id: ' + scope.id + ' scope:' + scope);
            });
            scope.$watch('cardId', function(oldValue, newValue) {
                console.log('$watch cardId: ' + oldValue + ' -> ' + newValue);
            });
            attrs.$observe(function() { return attrs.cardId }, function(newId) {
                console.log('ssssobserve card-id: new Value: ' + newId);
                console.log('sssssobserve card-id: id: ' + scope.id + ' scope:' + scope);
            });
            scope.$watch(function() { return attrs.cardId }, function(oldValue, newValue) {
                console.log('sssssssssss$watch card-id: ' + oldValue + ' -> ' + newValue);
            });
            console.log('linked card directive');
        }
    }
});

the watch and observer functions (with the exception of 'ssssobserver') get called on intialization when i set the values via ng-repeat.

Subsequent changes to the card-id attribute do not trigger the watch or observer code.

What do I need to do to get this working?

Upvotes: 3

Views: 1592

Answers (1)

Tyler
Tyler

Reputation: 11499

There are lots of things going on here that prevent this from working. The main advice I'd give is to learn the habits of Angular better (perhaps a few more tutorials) and to stamp jQuery's way of doing things out of your mind. Angular gives you a path to do almost everything through the javascript, so if you find yourself manipulating DOM elements, take a step back and try something different.

The most obvious improvement would be to use Angular's built-in messaging tools rather than try to roll your own through manipulating the DOM. Angular provides $rootScope.$on, $rootScope.$broadcast, and $rootScope.emit for these purposes.

There is also the notion of 2-way binding, which is not possible with replacement as you've attempted in your plunkr. I've forked another one and got it working, so have a look and see how you could be doing it differently.

http://plnkr.co/edit/eqZQ0iptzKAInEYxEyLp?p=preview

This is by no means "ideal" code -- just functional. Keep striving to learn the toolset and you'll be just fine.

Upvotes: 1

Related Questions