K
K
ksivasid2016-03-16 17:48:41
JavaScript
ksivasid, 2016-03-16 17:48:41

Angular, how to properly pass asynchronous data from factory->controller->directive?

Help me figure out the correct data transfer through the chain:
Factory -> parent controller -> directive
The problem arises with getting asynchronous data. If the data is known to exist, then everything seems to be clear. But as told the problem arises if I request the data from the server. Now I have to use watch in the controller and directive. As the gurus write, $scope cannot be used in controllers, but how can I keep track of data updates in the factory without $scope.watch, and the same situation with the directive, I also have to hang $scope.watch on the value that comes from the parent controller. If they are not hung up, respectively, I will get undefined in the directive for the object that I am trying to get. Explain how to properly arrange this order.
p / s I wrote an example quickly, and I didn’t check its performance, maybe I made a mistake in the code somewhere, but I think I can convey the essence of the problem.
Directive (in it I try to get the data that the factory will receive)

(function() {
    'use strict';

    angular
        .module('app')
        .directive('myDirective', myDirective);

    function myDirective() {
        var directive = {
            restrict: 'AE',
            replace: true,
            scope: true,
            controller: directiveCtrl,
            controllerAs: 'ctrl',
            bindToController: {
                model: '='
            },
            template: '<div><h2 data-ng-bind="ctrl.otheVar"></h2><p data-ng-bind="ctrl.otheModel"></p></div>',
            link: link
        };
        return directive;

        function link(scope, element, attrs, ctrl) {

        }
    }

    directiveCtrl.$inject = ['$scope'];

    function directiveCtrl($scope) {
        var vm = this;

        vm.otheModel = 1;
        vm.otheVar = 'fooBarFooBarFooBarFooBarFooBarFooBarFooBarFooBar';

        active();

        function active (){
            $scope.$watch(function (){return( vm.model );}, function (newValue, oldValue) {
                if (newValue !== oldValue) {
                    vm.otheModel = newValue * 10;
                    vm.otheVar = vm.otheVar + newValue;
                }
            });
        }
    }
})();

The directive's parent controller. It may contain other directives and different application logic
(function() {
    'use strict';

    angular
        .module('app')
        .controller('parentCtrl', parentCtrl);

    parentCtrl.$inject = ['$scope','parentFactory'];

    function parentCtrl($scope,parentFabric) {
        var vm = this;

        vm.model = {
            ajax: {},
            otheVar: true
        };

        $scope.$watch(function () {
            return parentFactory.getModel();
        }, function (newVal, oldVal) {
            if (newVal !== oldVal) {
                vm.model.ajax = newVal;
            }
        }, true);
    }
})();

Factory for working with data (in it I receive or manipulate data, through it I transfer data to other controllers)
(function() {
    'use strict';

    angular
        .module('app')
        .factory('parentFactory', parentFactory);

    parentFactory.$inject = ['$http'];

    function parentFactory($http) {

        var model = {};

        var service = {
            getModel : getModel,
            manipulateModel : manipulateModel,
            setModel : setModel
        };

        return service;

        active();

        function active(){
            service.setModel().then(
                function(data){
                    model = data.data;
                },function(){
                    console.log('error');
                }
            );
        }

        function getModel(){
            return model;
        }

        function manipulateModel(){
            model.foo = 'bar';
            //.
            //.
            //.
            //.
            //.
        }

        function setModel(){
            return $http({
                method: 'POST',
                url: 'http://FooBar.ru'
            }).success(function (data) {
            }).error(function () {
            });
        }
    }
})();

This is how I call the directive in the parent controller:
<div>
    .
    .
    .
    <my-directive model="vm.model.ajax"></my-directive>
    .
    .
    .
</div>

Answer the question

In order to leave comments, you need to log in

1 answer(s)
_
_ _, 2016-03-16
@ksivasid

https://github.com/rubenv/angular-tiny-eventemitter or reactive in the spirit of RxJS.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question