Estoy usando una directiva para llenar un gráfico usando la API de AmCharts. La función que se está utilizando actualmente enumera los datos que pueblan el formulario en formato JSON como un parámetro en la función. Quiero poder almacenar esto como una variable para poder tener un archivo separado para el JSON. Sé que probablemente tenga que usar $ http para obtener el json, pero no estoy seguro de cómo conectaría esto a la directiva.

var myapp = angular.module('tmn_portfolio', []);

myapp.directive('loadPortfolio',
 function () {
  return {
   restrict: 'E',
   replace:true,

   template: '<div id="chartdiv" style="min-width: 310px; height: 400px; margin: 0 auto"></div>',
   link: function (scope, element, attrs) {

        var chart = false;

        var initChart = function() {
          if (chart) chart.destroy();
          var config = scope.config || {};
           chart = AmCharts.makeChart("chartdiv", I WANT THIS TO BE A VARIABLE TO JSON FILE);

        };
        initChart();

 }//end watch           
  }
}) ;
0
Philip 3 sep. 2014 a las 17:54

2 respuestas

La mejor respuesta

Una mejor solución que scope: true sería pasar los datos a la directiva en un atributo. El marcado se verá así:

<load-portfolio my-data="jsonData" ></load-portfolio>

Ese elemento será reemplazado por su plantilla. En la directiva:

myapp.directive('loadPortfolio',
    function () {
        return {
            restrict: 'E',
            replace:true,
            scope: {
                myData: '='
            },
            template: '<div id="chartdiv" style="min-width: 310px; height: 400px; margin: 0 auto"></div>',
            link: function (scope, element, attrs) {
                var chart = false;
                var initChart = function() {
                    if (chart) chart.destroy();
                    var config = scope.config || {};
                    chart = AmCharts.makeChart("chartdiv", scope.myData);
                };
                initChart();
            }//end watch           
        }
    });

El signo igual es un enlace bidireccional entre la propiedad myData en el alcance de la directiva y la propiedad jsonData en el alcance de su controlador (el "modelo" en términos angulares). Cada vez que los datos cambien en el controlador, también cambiará en la directiva, y su IU se actualizará para reflejar eso.

Ahora solo tienes que obtener los datos json, ¿verdad? Tiene razón, probablemente debería usar $ http para hacer esto, y su aspecto dependerá de su implementación específica, pero la parte importante es que una vez que complete jsonData, su directiva se actualizará para reflejar que . Normalmente inicializo modelos que se completarán de forma asíncrona en mi controlador. Una versión muy simple podría verse así:

myapp.controller('myController', ['$scope', '$http', function($http, $scope) {
    $scope.jsonData = {};  // or '' - depending on whether you actually want the JSON string here.

    $http({
        url: '/data.json',
        method: 'GET'
    }).
    then(function(r) {
        $scope.jsonData = r.data;
    });
}]);

Creo que, para hacerlo correctamente, debería examinar el enrutamiento y la propiedad resolve de las rutas, lo que le permite recuperar los datos antes de que se cargue su controlador y pasarlo como un argumento al controlador, pero eso depende realmente de tú.

Actualización: Al igual que la otra respuesta, recomiendo usar una fábrica / servicio para llamadas a su servidor o API, en lugar de usar $ http directamente en el controlador como en mi ejemplo. Solo trato de mantenerlo simple aquí. El código angular es más divertido cuando está bien organizado.

0
threeve 3 sep. 2014 a las 14:50

Necesita una fábrica o servicio para solicitar primero su archivo JSON y almacenarlo como una variable:

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

app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}
]);


app.factory('data', function($http) { 
var data = {
    async: function() {
      // $http returns a promise, which has a then function, which also returns a promise
      var promise = $http.get('file.json').then(function (response) {
        // The then function here is an opportunity to modify the response
        console.log(response);
        // The return value gets picked up by the then in the controller.
        return response.data;
      });
      // Return the promise to the controller
      return promise;
    }
  };
  return data;
});

app.controller('MainCtrl', function( data,$scope) {
  // Call the async method and then do stuff with what is returned inside our own then function
  data.async().then(function(d) {
    $scope.jsonData = d; ;
  });

});
0
Andrew 3 sep. 2014 a las 14:43