64

Background

I have the most basic "newbie" AngularJS question, forgive my ignorance: how do I refresh the model via code? I'm sure it's answered multiple times somewhere, but I simply couldn't find it. I've watched some great videos here http://egghead.io and went quickly over the tutorial, but still I feel I'm missing something very basic.

I found one relevant example here ($route.reload()) but I'm not sure I understand how to use it in the example below

Here is the setup

controllers.js

function PersonListCtrl($scope, $http) {
  $http.get('/persons').success(function(data) {
    $scope.persons = data;
  });
}

index.html

...
<div>
    <ul ng-controller="PersonListCtrl">
        <li ng-repeat="person in persons">
            Name: {{person.name}}, Age {{person.age}}
        </li>
    </ul>
</div>
...

This all works amazingly well, each time the page is reloaded I see the list of people as expected

The questions

  1. Let's say I want to implement a refresh button, how do I tell the model to reload programmatically?
  2. How can I access the model? it seems Angular is magically instantiating an instance of my controller, but how do I get my hands on it?
  3. EDIT added a third question, same as #1 but how can it be done purely via JavaScript?

I'm sure I'm missing something basic, but after spending an hour trying to figure it out, I think it deserves a question. Please let me know if it's duplicate and I'll close + link to it.

Eran Medan
  • 44,555
  • 61
  • 184
  • 276

2 Answers2

72

You're half way there on your own. To implement a refresh, you'd just wrap what you already have in a function on the scope:

function PersonListCtrl($scope, $http) {
  $scope.loadData = function () {
     $http.get('/persons').success(function(data) {
       $scope.persons = data;
     });
  };

  //initial load
  $scope.loadData();
}

then in your markup

<div ng-controller="PersonListCtrl">
    <ul>
        <li ng-repeat="person in persons">
            Name: {{person.name}}, Age {{person.age}}
        </li>
    </ul>
   <button ng-click="loadData()">Refresh</button>
</div>

As far as "accessing your model", all you'd need to do is access that $scope.persons array in your controller:

for example (just puedo code) in your controller:

$scope.addPerson = function() {
     $scope.persons.push({ name: 'Test Monkey' });
};

Then you could use that in your view or whatever you'd want to do.

Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
Ben Lesh
  • 107,825
  • 47
  • 247
  • 232
  • Thanks, this is exactly what I was looking for, is there a way to access that loadData() function from javascript instead of via the `ng-click` directive? – Eran Medan Feb 04 '13 at 19:25
  • You wouldn't want to do that.... You could... but you probably don't want to. It's not the angular way. – Ben Lesh Feb 04 '13 at 19:26
  • hm... My thought was this - have an "add" method that adds a person, and then when it's done adding, I would like to refresh the model from the server, so I understand that the Angular way is to update the model by adding a person to it, then save it to the server, and avoid the extra "reload to verify?" p.s. when you say "you could", then how exactly? :) – Eran Medan Feb 04 '13 at 19:28
  • Is it via 'angular.element(domElement).scope()'? – Eran Medan Feb 04 '13 at 19:30
  • 4
    I feel dirty telling you this... because you really, really shouldn't... but you can get the [scope from a DOM element](http://stackoverflow.com/questions/10490570/call-angular-js-from-legacy-code). `angular.element(domElem).scope()` ... but don't do that. lol – Ben Lesh Feb 04 '13 at 19:31
  • 1
    The angular way to do this would be to just use that `loadData()` function I made to reload the data from the server. and maybe that `addPerson()` method I made does a save via AJAX and on success it calls `loadData()` – Ben Lesh Feb 04 '13 at 19:32
  • got it, I need to start thinking of the Controller as the main Business Logic location I guess, thanks for all the help! – Eran Medan Feb 04 '13 at 19:33
  • @blesh In reference to using a DOM element to get a scope, why should one not do this and how should it be done instead? I am writing a WebGL game using Three.js. I have a UI that is overlayed on my canvas so I started looking into Angular to asynchronously refresh that UI when game state changes. I have a controller and view set up much like Eran Medan. How should I continue to update the $scope after initialization? – theblang May 28 '13 at 04:47
  • Well, you *can* do it that way, of course, but it's going to break the MVC pattern of Angular, and it's also going to make your JavaScript much harder to test. One of the biggest advantages of Angular and the "angular way" is that if you do things properly your code is loosely coupled and easy to test. – Ben Lesh May 28 '13 at 14:14
  • @BenLesh But the Question still exists: what, if I have an function insight a controller (like `loadData()`), that I need to execute again and again in order to refresh the data. For example, if the application himself modified the data... So how is the "correct" angular/MVC way? – The Bndr Jun 05 '14 at 12:28
2

Before I show you how to reload / refresh model data from the server programmatically? I have to explain for you the concept of Data Binding. This is an extremely powerful concept that will truly revolutionize the way you develop. So may be you have to read about this concept from this link or this seconde link in order to unterstand how AngularjS work.

now I'll show you a sample example that exaplain how can you update your model from server.

HTML Code:

<div ng-controller="PersonListCtrl">
    <ul>
        <li ng-repeat="person in persons">
            Name: {{person.name}}, Age {{person.age}}
        </li>
    </ul>
   <button ng-click="updateData()">Refresh Data</button>
</div>

So our controller named: PersonListCtrl and our Model named: persons. go to your Controller js in order to develop the function named: updateData() that will be invoked when we are need to update and refresh our Model persons.

Javascript Code:

app.controller('adsController', function($log,$scope,...){

.....

$scope.updateData = function(){
$http.get('/persons').success(function(data) {
       $scope.persons = data;// Update Model-- Line X
     });
}

});

Now I explain for you how it work: when user click on button Refresh Data, the server will call to function updateData() and inside this function we will invoke our web service by the function $http.get() and when we have the result from our ws we will affect it to our model (Line X).Dice that affects the results for our model, our View of this list will be changed with new Data.

BERGUIGA Mohamed Amine
  • 6,094
  • 3
  • 40
  • 38