4

I have a VF page that uses the AngularJS framework. I am not convinced that I am initializing my page correctly and would like to know what best practice actually is.

Current page init process

  • VF page that contains just apex:page component and pure html is generated server side.
  • This page is sent to the browser and rendered client-side.
  • AngularJS initializes.
  • Part of an AngularJS controller involves a JavaScript Remoting request which (a) obtains picklist values, (b) retrieves the form state data.
  • On completion of the remoting call, the picklist options are populated and the form state is set via ngModel.

Issue

  • The request for data is only done on page load (when the AngularJS controller code is executed), so the user first sees a blank form, and then there is a slight delay before the picklist options and the form state data populates, which doesn't look good.

Questions

  • Is this the standard way that people are initializing a page using AngularJS with VF?
  • I was trying to see if I could use a solution that used VF formula expressions ({!MyWrapperClass}) to initialize the JavaScript scope with data so that all of the JavaScript objects would be already be there onload, but although this is possible with primitive values, it doesn't come out right with arrays, sobjects, or wrapper classes. Is there a better way that I can do this?

Thanks for reading

Edit

I have found one solution which seems to work quite well.

  • Query the data in the Apex controller and convert is to json using: jsonData = JSON.serialize(MyWrapperClass)
  • Then on the client side, use a formula expression and the angular.fromJson() method it initialize the JavaScript object used as the angular model.

    angular.module('myApp', [])
           .controller('MyController', function($scope) {
               $scope.data = angular.fromJson({!jsonData});
           });
  • I follow this pattern of using the controller to initialize data if possible. Then use JavaScript for all updates – Phil B May 30 '15 at 18:01
4

Yes, you can speed that up.

But on a slower connection, you still might get the flash.

I like to use ng-cloak so that in-process stuff doesn't show until it's got data.

| improve this answer | |
3

Sounds like you already answered your own question. I would just add to your solution that you should use a closure and get yourself out of the global namespace!

(function (a) {
    a.module('myApp', [])
        .controller('MyController', function ($scope) {
            $scope.data = a.fromJson({!jsonData});
        })
})(angular);
| improve this answer | |
  • The magic of the IFFE! – Phil B May 30 '15 at 17:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.