P
P
pofigizm2014-05-25 09:02:10
JavaScript
pofigizm, 2014-05-25 09:02:10

How to delay building a document or processing a directive until data is received from the server?

js file:

'use strict';
angular.module('myApp')
  .factory('Order', ['$resource',
    function ($resource) {
      return $resource('/api/orders/:id', { id: 'all' } );
    }
  ])
  .controller('orderCtrl', ['$scope', '$routeParams', 'Order',
    function ($scope, $routeParams, Order) {
// Если здесь не заполнить скоп то в обработке директивы будет ошибка
      $scope.orders = [{
        name: 'name'
      }];
      console.log('controller');
      Order.query({id: 'all'}, function(orders) {
        $scope.orders = orders;
        console.log('get data from server');
      });
    }
  ])
  .directive('orderDrct', ['$compile',
    function ($compile) {
      return {
        restrict: 'A',
        link: function (scope, element) {
          var html = '';
          angular.forEach(scope.orders, function (ord) {
            html += '<h4>' + ord.name + '</h4>';
          });
          element.append($compile(html)(scope));
          console.log('end of directive');
        }
      };
    }
  ]);

in the console messages in this order:
controller
end of directive
get data from server

and part of my html (I have everything in jade, I hope it will be clear):
div.marketing 
  h3 It made with ng-repeat
  div.order(ng-repeat='order in orders')
    h4 {{order.name}}

div.marketing 
  h3 It made with derective
  div(order-drct)

The 1st block is built using ng-repeat and it is rebuilt after the data
arrives. The 2nd one is actually what I need, but I want it to be built when the data comes from the server.
UPDATE 05/29/14! (pulled here from a comment)
I don't want to repeat ng-repeat, I have a completely different task.
In my form, the set of fields is built according to the data that came from the server (I simplified it as much as possible to understand the task):
jsbin.com/tafuw/3/watch
Actually, everything works for me, there are no problems, but I am interested in opinions about the correctness or incorrectness of such a solution .
UPDATE 05/31/14!
In general, what I need can be implemented without any directive at all, using ng-switch.
Of course, this is not entirely on the topic of the question, but still I will leave it here, maybe someone will need it.
jsbin.com/repidexo/2/watch

Answer the question

In order to leave comments, you need to log in

3 answer(s)
N
Nikita Gushchin, 2014-06-03
@pofigizm

I used $broadcast for such a task. In your case, add a 'dataloaded' message to the controller:

Order.query({id: 'all'}, function(orders) {
        $scope.orders = orders;
        console.log('get data from server');
        $scope.$broadcast('dataloaded');
      });

And in the directive, make initialization when the dataloaded event occurs :
.directive('orderDrct', ['$compile',
    function ($compile) {
      return {
        restrict: 'A',
        link: function (scope, element) {
          scope.$on('dataloaded', function ()
          {
              // Ваш код
              console.log('end of directive');
          });          
        }
      };
    }
  ]);

In this case, your code will execute after the dataloaded event arrives .

M
maxaon, 2014-05-28
@maxaon

You need to spend more time learning angular and its philosophy.
In the simplest case, your directive code will look like this :
jsbin.com/dekic/13/edit

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question