2

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";
    }
}
2
  • Does $scope.formdata.reports.first_name work in your directive? Commented Apr 3, 2014 at 14:51
  • Yes, and the databinding works also. Commented Apr 3, 2014 at 15:01

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

Wow that helps so much. I knew I was overthinking this!
0

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.

1 Comment

I'm doing this so ng-model="formdata.reports.first_name" can be changed to either "first_name" or "formdata.reports.fe.fi.fo.fum.first_name" without breaking my directive. I don't know, maybe I'm overthinking things?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.