10

I'm newbie of angularjs developing and i wrote this simple app, but don't understand how i can update view, after the model il loaded from ajax request on startup!

This code don't work when I add delay into photos.php, using: sleep(3); for simulate remote server delay! instead if search.php is speedy it work!!

<!doctype html>
<html ng-app="photoApp">
<head>
<title>Photo Gallery</title>
</head> 
<body>
    <div ng-view></div>

<script src="../angular.min.js"></script>
<script>
'use strict';

var photos = [];  //model

var photoAppModule = angular.module('photoApp', []);

photoAppModule.config(function($routeProvider) {
    $routeProvider.when('/photos', {
                        templateUrl: 'photo-list.html',
                        controller: 'listCtrl' });
    $routeProvider.otherwise({redirectTo: '/photos'});
})
.run(function($http) {
    $http.get('photos.php')//load model with delay
    .success(function(json) {

        photos = json; ///THE PROBLEM HERE!! if photos.php is slow DON'T update the view!

    });
})
.controller('listCtrl', function($scope) {

    $scope.photos = photos;

});
</script>
</body>
</html>

output of photos.php

[{"file": "cat.jpg", "description": "my cat in my house"},
 {"file": "house.jpg", "description": "my house"},
 {"file": "sky.jpg", "description": "sky over my house"}]

photo-list.html

<ul>
  <li ng-repeat="photo in photos ">
    <a href="#/photos/{{ $index }}">
        <img ng-src="images/thumb/{{photo.file}}" alt="{{photo.description}}" />
    </a>
  </li>
</ul>

EDIT 1, Defer solution:

.run(function($http, $q) {

    var deferred = $q.defer();

    $http.get('photos.php')//load model with delay
    .success(function(json) {
        console.log(json);

        photos = json; ///THE PROBLEM!! if photos.php is slow DON'T update the view!

        deferred.resolve(json);//THE SOLUTION!
    });

    photos = deferred.promise;
})

EDIT 2, Service solution:

... 
//require angular-resource.min.js
angular.module('photoApp.service', ['ngResource']).factory('photoList', function($resource) {
    var Res = $resource('photos.php', {},
        {
            query: {method:'GET', params:{}, isArray:true}
        });
    return Res;
});

var photoAppModule = angular.module('photoApp', ['photoApp.service']);

...

.run(function($http, photoList) {

    photos = photoList.query();
})
...

4 Answers 4

6

The short answer is this:

.controller('listCtrl', ['$scope', '$timeout', function($scope, $timeout) {
    $timeout(function () {
        $scope.photos = photos;
    }, 0);
}]);

The long answer is: Please don't mix regular javascript and angular like this. Re-write your code so that angular knows what's going on at all times.

var photoAppModule = angular.module('photoApp', []);

photoAppModule.config(function($routeProvider) {
    $routeProvider.when('/photos', {
        templateUrl: 'photo-list.html',
        controller: 'listCtrl' 
    });

    $routeProvider.otherwise({redirectTo: '/photos'});
});

photoAppModule.controller('listCtrl', ['$scope', function($scope) {
    $scope.photos = {};

    $http.get('photos.php') // load model with delay
        .success(function(json) {
            $scope.photos = json; // No more problems
        });
}]);
Sign up to request clarification or add additional context in comments.

Comments

4

use broadcast

//service 
var mydata = [];
this.update = function(){
  $http.get(url).success(function(data){
    mydata = data;
    broadcastMe();
  });
};
this.broadcastMe = function(){ 
  $rootScope.$broadcast('mybroadcast');
};

//controller
$scope.$on('mybroadcast', function(){
  $scope.mydata = service.mydata;
};

http://bresleveloper.blogspot.co.il/

EDIT:couple of days ago i've learned the best practice http://bresleveloper.blogspot.co.il/2013/08/breslevelopers-angularjs-tutorial.html

Comments

1

I think you're better off using high level angular services for data transfer, also look into promises and services:

http://docs.angularjs.org/api/ng.$q

3 Comments

yes work, but I do not know if it's the best solution that is typically used in angularjs. please look my EDIT 2, is a second solution that uses a service, I would just like to know if the service goes well defined in this mode. which do you think is the most elegant of the two?? thanks!
Services is the way to go in my opinion. For one, it's reusable across all of your controllers.
tnk! yes im just verify it in other discussions
0

You need to bind an element in your view to a property (simple or object) of your $scope object. Once the $scope object is updated the view should be updated on its own. That is the beauty of AngularJS.

EDIT: Please register your controller as

photoAppModule.controller('listCtrl', function($scope){
  $scope.photos = photos;

});

If photos variable is not available, then you might have to create a service with the variable and inject in the controller.

5 Comments

I'm added the view.. look my edit. I'M just bind $scope.photos = photos; But if i edit photos... the view not change
I suspect that you did not register the controllers with Angular. photoAppModule.controller('listCtrl', function($scope){}); instead of just a regular function. That might work.
perhaps :) but i don't understand how register the controller
I'm rewrite all code more clear.. with your suggest! but dont work if ajax request is delayed
Yes, I forgot that there would be a race condition as the code in the controller will run directly even if there is nothing in photo yet. I think the deferred should work.

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.