0

I have an Angular scope that looks something like this:

{
  node_type: 100, node_instance: 001, value: 'pony', show: true, childNodes: {
    node_type: 100, node_instance: 011, value: 'cat', show: false, childNodes: {
      node_type: 101: node_instance: 001, value: 'apple'show: true, 
    }
    node_type: 100: node_instance: 012, value: 'kitty', show: true, 
    node_type: 100: node_instance: 013, value: 'meow', show: true, 
  }
  node_type: 100, node_instance: 002, value: 'horse', show: true, childNodes: {
    node_type: 102: node_instance: 001, value: 'dog', show: false, 
    node_type: 100: node_instance: 014, value: 'mutt', show: true, 
  }
}

It's obviously much (much) deeper and more complex than this.

Upon making various actions (say, changing "mutt" to "Fido"), my server will return newly updated, seemingly unrelated data in a set like…

{ node_type:101, node_instance:001, show:false }

I've found various ways of traversing the scope to find the 101,001 node, but they all involve sending copies of scope nodes to a traversal function, updating properties in a copy is worthless. How can I tell the function to update the scope at the correct address, or update node properties by reference?

(Or is the solution as dumb as setting a data="show" property in the DOM, updating the DOM outside of Angular, and then setting a scope.apply() request? I've had bad luck with scope.apply()…)

  • So the "Angular way" is to have your models exist in the uppermost common scope. If, for instance, this is the root scope, can you not get to it by merely injecting $rootScope into your controllers? – Ram Rajamony May 08 '13 at 22:24
  • when you pass object in javascript to any function that is passed by value but the value that is passed is actually a reference rather than the object itself so it you update scope propeties in traversal function it would not be a worthless exercise. This link will make it more clear :http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language – Ajay Beniwal May 09 '13 at 05:08
  • re: Ram — if you're suggesting that I reload the entire dataset from the root controller, that causes the interface to reload, thus causing the user to lose his place in the a rather complex form. – user2246897 May 10 '13 at 14:42
  • re: Ajay, thank you for the link. Task still looks challenging, but that could help. – user2246897 May 10 '13 at 14:42

1 Answers1

0

The solution was twofold.

First, to deep-traverse the $scope.data (which stores the json), as per this example.

Second, to update via reference as Ajay describes.

Using the traverse() function above…

for( var i = 0; i < response.nodes.length; i++ ) {
    traverse( $scope.data, response.nodes[i], 
        function(key, val, update) {
            if( val != null && typeof val.node_type != 'undefined' 
                && update.node_type == val.node_type 
                && update.node_instance == val.node_instance 
            ) {
                val.show = update.show;
            }
        }
    );
}

Thank you Ajax for your assistance, and Stack Overflow at large. What a terrific world we live in.

Community
  • 1
  • 1