简体   繁体   中英

Converting an array to a nested object

What I'm trying to do: I am trying to dynamically update a scope with AngularJS in a directive, based on the ngModel.

A little back story: I noticed Angular is treating my ngModel strings as a string instead of an object. So if I have this:

ng-model="formdata.reports.first_name"

If I try to pull the ngModel in a directive, and assign something to it, I end up with $scope["formdata.reports.first_name"]. It treats it as a string instead of a nested object.

What I am doing now: I figured the only way to get this to work would be to split the ngModel string into an array, so I am now working with:

models = ["formdata", "reports", "first_name"];

This works pretty good, and I am able to use dynamic values on a static length now, like this:

$scope[models[0]][models[1]][models[2]] = "Bob";

The question: How do I make the length of the dynamic scope dynamic? I want this to be scalable for 100 nested objects if needed, or even just 1.

UPDATE: I was able to make this semi-dynamic using if statements, but how would I use a for loop so I didn't have a "max"?

if (models[0]) {
    if (models[1]) {
        if (models[2]) {
            if (models[3]) {
                $scope[models[0]][models[1]][models[2]][models[3]] = "Bob";
            } else {
                $scope[models[0]][models[1]][models[2]] = "Bob";
            }
        } else {
            $scope[models[0]][models[1]] = "Bob";
        }
    } else {
        $scope[models[0]] = "Bob";
    }
}

This is an answer to

I noticed Angular is treating my ngModel strings as a string instead of an object

Add the require property to your directive then add a fourth ctrl argument to your link function

app.directive('myDirective', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attributes, ctrl) {
      // Now you have access to ngModelController for whatever you passed in with the ng-model="" attribute
      ctrl.$setViewValue('x');
    }
  };
});

Demonstration: http://plnkr.co/edit/Fcl4cUXpdE5w6fHMGUgC

Dynamic pathing:

var obj = $scope;

for (var i = 0; i<models.length-1; i++) {
  obj = obj[models[i]];
}
obj[models[models.length-1]] = 'Bob';

Obviously no checks are made, so if the path is wrong it will fail with an error. I find your original problem with angular suspicious, perhaps you could explore a bit in that direction before you resort to this workaround.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM