2

I'm adding a mild amount of angularjs to my existing application. I'm starting with utilizing controllers to manage my forms which are all submitted by ajax. The forms are currently pulled into the page using jQuery's $.load() function and the form elements already have values.

I'd like my models I've assigned into $scope to have these values available. For example:

<form>
  <input type="text" ng-model="user.firstName" value="Gregg" />
  <input type="text" ng-model="user.lastName" value="Bolinger" />
  <button ng-click="update(user)">Save</button>
</form>

And then in my main.js file I would have something like the following:

function UserCtrl($scope) {
  $scope.update = function(user) {
    // update the user
  };
}

As is, my form input elements are blank because the ng-model is empty. Is there a way to initialize my ng-model with the existing values in the form?

BTW, I did read this SO Question which is the same as mine, however, I'm hoping for a better answer than some window scoped global variable.

Community
  • 1
  • 1
Gregg
  • 34,973
  • 19
  • 109
  • 214
  • 1
    I don't think there's any simple way to do this in AngularJS as it's not how it's designed to work. What you could do though is write a directive that wraps the form element. Then, from the directive, you can get the attribute values and assign them to the user properties. – laurent Jun 17 '13 at 02:10

1 Answers1

6

The big issue here really is that in your current setup, jQuery is operating outside of the angular world. It has no concept of angular scopes, or any real way of accessing them without being a little bit hacky and going against how angular works, BUT you can do this if you want.

After you've loaded your data from jQuery, rather than setting the values of your form, you can just set the values directly within the angular models. If for example you had your page something like

<div class="wrapper" ng-controller="UserCtrl">
    <form>
        ... inputs as in your post ...
    </form>
</div>

Then inside your controller, put

$scope.user = {
    firstName: "",
    lastName: ""
}

Then you're actually able to get the angular scope from jQuery at any point. In this example, you would simply do

$(".wrapper").scope();

So, in your jQuery, you could fetch your data as you're doing, and then just assign the values within the scope. So for example, you could do something such as

var user = ... load data with jquery here ...;
var scope = $(".wrapper").scope();
var $user = scope.user;
scope.$apply(function() {
    $user.firstName = user.firstName;
    $user.lastName = user.lastName;
});

In theory this should do what you're after.

I would however highly recommend you move your data loading to angular as well, as this makes life a lot easier and less confusing. Angular makes data loading just as easy as jQuery does as well which is nice, and if you were to use ngResource (which personally I love) you could fetch a user by simply doing

User.get({ id: user_id_here })

And that's it. Then in your controller, you'd just have

$scope.user = User.get({ id: user_id_here })

And the form would be set to go :)

But as I say, you can have it run inline with your current structure if you wish

PaReeOhNos
  • 4,338
  • 3
  • 30
  • 41
  • Thanks. I understan moving the data loading to Angular, but then I'm making 2 requests to the server every time the form is displayed. Once to show the form and again to pull the data. That makes no sense. The only way to benefit is to have angular display the form via a template and then load the data and that is too much of an undertaking for me right now. Just trying to do small chunks rather than a re-write. – Gregg Jun 17 '13 at 04:17
  • That's true you'd have 2 requests, but this way you'll have to fetch the entire form again if you want to edit a different record. If you have angular handle the data, then you'd initially have 2 requests for the form and the user, but the next user would only require a fetch of a user object and not the entire form again :) It is quite a learning curve though so perhaps try a new project with it at some point to figure things out. It's great once you get the hang of it :) – PaReeOhNos Jun 17 '13 at 05:17