AngularJS: фабрика для возврата данных из службы php с использованием $http

Я новичок в js, и это мой первый вопрос в stackoverflow. Так что любой комментарий или акт понижения рейтинга понятен.

Это проект angular-js-flowchart на github. Это еще одна тема stackoverflow, в которой рассказывается, как использовать factory в качестве средства получения данных с участием $http.

Мне нужно сгенерировать данные для диаграммы с помощью фабрики Angular, которая возвращает функцию $http. $http взаимодействует со службой php, которая извлекает данные из базы данных. Я протестировал сервис с помощью jsonlint, и он отлично работает. Каталог сервиса проверяется относительно html файла.

Я скопировал «заводской» код из другого вопроса stackoverflow и применил его к app.js в проекте angularjs-flowchart Github.

Проблема в том, что консоль Chrome продолжает выдавать ошибку, которую я не могу понять. Данные не извлекаются. Ошибка на консоли "TypeError: Невозможно прочитать свойство getData неопределенного"

Это модифицированный мной app.js:

//
// Define the 'app' module.
//
angular.module('app', ['flowChart', ])

//
// Simple service to create a prompt.
//
.factory('prompt', function () {

    /* Uncomment the following to test that the prompt service is working as expected.
    return function () {
        return "Test!";
    }
    */

    // Return the browsers prompt function.
    return prompt;
})

//
// Application controller.
//
.controller('AppCtrl', ['$scope', 'prompt', function AppCtrl ($scope, prompt, dataFactory) {

    //
    // Code for the delete key.
    //
    var deleteKeyCode = 46;

    //
    // Code for control key.
    //
    var ctrlKeyCode = 65;

    //
    // Set to true when the ctrl key is down.
    //
    var ctrlDown = false;

    //
    // Code for A key.
    //
    var aKeyCode = 17;

    //
    // Code for esc key.
    //
    var escKeyCode = 27;

    //
    // Selects the next node id.
    //
    var nextNodeID = 10;


    //
    // Event handler for key-down on the flowchart.
    //
    $scope.keyDown = function (evt) {

        if (evt.keyCode === ctrlKeyCode) {

            ctrlDown = true;
            evt.stopPropagation();
            evt.preventDefault();
        }
    };

    //
    // Event handler for key-up on the flowchart.
    //
    $scope.keyUp = function (evt) {

        if (evt.keyCode === deleteKeyCode) {
            //
            // Delete key.
            //
            $scope.chartViewModel.deleteSelected();
        }

        if (evt.keyCode == aKeyCode && ctrlDown) {
            // 
            // Ctrl + A
            //
            $scope.chartViewModel.selectAll();
        }

        if (evt.keyCode == escKeyCode) {
            // Escape.
            $scope.chartViewModel.deselectAll();
        }

        if (evt.keyCode === ctrlKeyCode) {
            ctrlDown = false;

            evt.stopPropagation();
            evt.preventDefault();
        }
    };

    //
    // Add a new node to the chart.
    //
    $scope.addNewNode = function () {

        var nodeName = prompt("Enter a task name:", "New Task");
        if (!nodeName) {
            return;
        }

        //
        // Template for a new node.
        //
        var newNodeDataModel = {
            name: nodeName,
            id: nextNodeID++,
            x: 0,
            y: 0,
            inputConnectors: [ 
                {
                    name: "Pre"
                }           
            ],
            outputConnectors: [ 
                {
                    name: "Sub"
                }           
            ],
        };

        $scope.chartViewModel.addNode(newNodeDataModel);
    };

    //
    // Add an input connector to selected nodes.
    //
    $scope.addNewInputConnector = function () {
        var connectorName = prompt("Enter a connector name:", "New connector");
        if (!connectorName) {
            return;
        }

        var selectedNodes = $scope.chartViewModel.getSelectedNodes();
        for (var i = 0; i < selectedNodes.length; ++i) {
            var node = selectedNodes[i];
            node.addInputConnector({
                name: connectorName,
            });
        }
    };

    //
    // Add an output connector to selected nodes.
    //
    $scope.addNewOutputConnector = function () {
        var connectorName = prompt("Enter a connector name:", "New connector");
        if (!connectorName) {
            return;
        }

        var selectedNodes = $scope.chartViewModel.getSelectedNodes();
        for (var i = 0; i < selectedNodes.length; ++i) {
            var node = selectedNodes[i];
            node.addOutputConnector({
                name: connectorName,
            });
        }
    };

    //
    // Delete selected nodes and connections.
    //
    $scope.deleteSelected = function () {

        $scope.chartViewModel.deleteSelected();
    };


    //
    // Setup the data-model for the chart.
    //
    var chartDataModel = {};
    var handleSuccess = function(data, status){
        chartDataModel = data;
        console.log(chartDataModel);
    };

    dataFactory.getData().success(handleSuccess);

    //
    // Create the view-model for the chart and attach to the scope.
    //
    $scope.chartViewModel = new flowchart.ChartViewModel(chartDataModel);
}])
.factory('dataFactory', function($http){
    return {
        getData : function(){
            return $http.post("chart-data-retrieve.php");
        }
    };

});

В принципе, то, что я добавил, но не работает,

// Setup the data-model for the chart.
//
var chartDataModel = {};
var handleSuccess = function(data, status){
    chartDataModel = data;
    console.log(chartDataModel);
};

dataFactory.getData().success(handleSuccess);

а также

.factory('dataFactory', function($http){
    return {
        getData : function(){
            return $http.post("chart-data-retrieve.php");
        }
    };

});

Пожалуйста, помогите, спасибо.


person locnguyen    schedule 20.06.2014    source источник


Ответы (2)


Я попытался установить chartViewModel $scope непосредственно внутри вызова службы, поэтому переменная chartDataModel становится избыточной. И это работает.

// Create the view-model for the chart and attach to the scope.
//
myService.then(function(data) {
    $scope.chartViewModel = new flowchart.ChartViewModel(data);
});
person locnguyen    schedule 26.06.2014

Я пытался вернуть обещание, а не $http с завода. Теперь это работает. Теперь контроллер может использовать службу для получения данных. Однако я все еще не мог установить переменную контроллера для извлеченных данных. Ниже приведен код:

.factory('myService', function($http, $q) {
  //this runs the first time the service is injected
  //this creates the service
  var deferred = $q.defer();

  $http.get('chart-data-retrieve.php').then(function(resp) {
    deferred.resolve(resp.data);
  });

  return deferred.promise;
})

И код внутри контроллера:

var chartDataModel = {};
//get data from myService factory
myService.then(function(data) {
    alert(data);
    chartDataModel = data;
});

В настоящее время alert() уже показывает мне данные. Однако переменная chartDataModel по-прежнему не установлена.

person locnguyen    schedule 25.06.2014