Question

I have this directive


MyApp.directive('dynatree', function ($rootScope) {
    return {
        restrict: 'E',
        link: function postlink(scope, element, attrs) {
            $(element).dynatree({
                onActivate: function (node) {
                    scope.$emit('nodeActivated', node);
                },
                persist: false,
                children: scope.treeData //this variable is in the layout for either csb or sku
            });
        }
    };
});


My controller contains the values for children:


scope.treeData = [ ... ]



Every time I update scope.treeData, my directive does not update. Does anyone have any idea on how to update my directive from my controller?

Thank you

Was it helpful?

Solution 2

Using scope.$watch is the way to go - as the guys mentioned before. When watching objects I found necessary to use 'true' as additional parameter

$watch("tree.data", function () {..}, true)

so comparizon won't be lazy and will check deeper then just references.

http://docs.angularjs.org/api/ng.$rootScope.Scope

OTHER TIPS

I've never worked with dynatree but it seems that the tree is not being redrawn when the src array changes.

Try watching for changes on scope.tree.data and reload the dynatree when it occurs:

MyApp.directive('dynatree', function ($rootScope) {
    return {
        restrict: 'E',
        link: function postlink(scope, element, attrs) {
            $(element).dynatree({
                onActivate: function (node) {
                    scope.$emit('nodeActivated', node);
                },
                persist: true,
                children: scope.tree.data //this variable is in the layout for either csb or sku
            });

            scope.$watch('tree.data', function() {
                // try to update the tree data here (I'm not aware how it's done)
                // and after that, reload...
                $(element).dynatree("getTree").reload();
            });
        }
    };
});

If there's no way to update the tree data, try destroying the dynatree and recreating it (inside the watcher function):

// destroy tree
$(element).dynatree("destroy");    
// recreate tree with new data
$(element).dynatree({ ... children: scope.tree.data ... });

Note that I've used tree.data and not treeData, that's because you should not store this kind of information directly on the scope, instead you should store it inside a model (i.e. scope.tree = { data: [ ... ] }).

How would Dynatree know that you changed the treeData? You probably need to tell it by installing a watcher on the treedata in your directive:

scope.$watch('treeData', function(treeData, old, scope){
  element.dynatree().howEverDynatreeIsUpdated();
})

I don't know dynatree, but if it's supposed to update itself, note that this will only work for modifications within the tree.

Replacing the entire tree with another one on the scope (= setting the scopes treeData property to something else) will not be detected by Dynatree, because the tree you passed into Dynatree during creation is the only one Dynatree can ever know about. It cannot, without manual interference, know that the treeData property on the scope has changed and it's own reference is pointing to an outdated one. You need to tell it somehow.

OK so the answer is


            scope.$watch('treeData', function (treeData, old, scope) {
                if (treeData.children) {
                    $(element).dynatree({children: treeData.children});
                    $(element).dynatree("getTree").reload();
                    $(element).show();
                }
            }, true)

It's not enough to just change the data of the tree, one has to reload it... I added the show because I'm hiding it before so that you don't see it bounce with the data changes

There are 2 ways to bind your variable inside AngularJs directive.First way is used,when you don't want to have isolated scope.You set watcher on attribute field.The second way is used,when you have isolated scope.this way is more professional.You set watcher only on your scope's variable. if you want more,here is a good article.

http://www.w3docs.com/snippets/angularjs/bind-variable-inside-angularjs-directive-isolated-scope.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top