Working with Factory

0

I am developing a system for a cafeteria, where it will have to register the cities and within the cities the districts with their due freights, the problem is occurring the first time that occurs the registration of the first neighborhood of the city, because it follows all the logic and tries to reload the function carregarBairros() that is inside another controller , as it is presented below:

HTML code

<div ng-hide="consultaativa" class="catalogo md-whiteframe-1dp col-md col-xs-12 col-sm-12 padding-zero" >

    <div  class="texto_catalogo" id="catalogo_{{cidade.cid_atd_id}}" style="padding-top: 30px;">
        <form name="bairroForm" >
            <div style="height:70px;" ng-model="box_alterar" ng-hide="hideAlterar" class="box_alt_bairros">
                <div layout-gt-sm="row" style="width:650px;">
                    <md-input-container flex ng-class="{'md-input-invalid': validaBairro.nomeinv}" >
                        <label>Bairro</label>
                        <input class="moeda" style="width: 300px;" ng-blur="validarBairro(1, validaBairro.nome)" ng-click="validarBairro(0, validaBairro.nome)" ng-keyup="validarBairro(0, validaBairro.nome)" type="text"  name="bairro" ng-model="validaBairro.nome" autofocus />
                        <div  class="error" ng-if="validaBairro.nomeinv" role="alert" multiple>
                            <div ng-message="required" class="my-message">Preencha o campo Bairro</div>
                        </div>
                    </md-input-container>
                    <md-input-container flex ng-class="{'md-input-invalid': validaFrete.freteinv}">
                        <label>Frete</label>
                        <input ng-model="validaFrete.frete" name="frete" ng-blur="validarFrete(1)" ng-click="validarFrete(0)" ng-keyup="validarFrete(0)" id="valor" mask-money style="width: 300px;padding: 0px;" type="text"/>
                        <div class="error" ng-if="validaFrete.freteinv" role="alert" multiple>
                            <div ng-message="required" class="my-message">Preencha o campo Frete</div>
                        </div>
                    </md-input-container>
                </div>
            </div>
            <div class="col-md-3 teste padding-zero pull-right" style="margin-top: 10px;">
                <section layout="row" layout-sm="column" class="pull-right" layout-wrap>
                    <md-button ng-click="cancelarAlteracao()" ng-if="alterar" class="md-raised md-warn pull-right">
                        <i class="fa fa-close"></i>
                        Cancelar
                    </md-button>

                    <md-button ng-click="validaForm(validaBairro.nome, cidade.cid_atd_id)" type="submit" ng-submit="validaForm(validaBairro.nome, cidade.cid_atd_id)" class="md-raised md-primary pull-right">
                        <i class="fa fa-save"></i>
                        Salvar
                    </md-button>
                    <div class="label"></div>
                </section>
            </div>
        </form>


        <div style="height: 50px;"></div>
    </div>
</div>



$scope.validaForm = function (bairro, cidade) {
    var valor = $("#valor").val();
    if ($scope.validaBairro.nomeinv === false && $scope.validaFrete.freteinv === false && $scope.validaBairro.nome !== '' && valor !== '0,00' && valor !== '') {
        if ($scope.alterar === false) {
            $scope.adicionarBairro(bairro, cidade, valor);
        } else {
            $scope.updateBairro($scope.id_bairro, cidade, bairro, valor);
        }
        $scope.validaBairro.nomeinv = false;
        $scope.validaFrete.freteinv = false;
    } else {
        $scope.validarBairro(1, bairro);
        $scope.validarFrete(1);
    }
};

$scope.adicionarBairro = function (bairro, cidade, valor) {
    $http.post(url_sistema + 'mostrarcidades/cadastrar_bairro', {'nome': bairro, 'cidade': cidade}).success(function (data, status, headers, config) {
        delete $scope.bairro; // se nao colocar esta linha, quando alterar o campo ele altera o dado da tabela tambem
        if (data < 1) {
            $http.post(url_sistema + 'mostrarcidades/cadastrar_frete', {'nome': bairro, 'cidade': cidade, 'valor': valor}).success(function (data, status, headers, config) {
                delete $scope.bairro;
            }).error(function (data, status) {
                console.log(data);
            });
            $mdToast.show(
                    $mdToast.simple()
                    .content('Cadastrado com sucesso!')
                    .theme("success-toast")
                    .position("top right")
                    .hideDelay(2000)
                    );
            Scopes.get('mostrarCidadesCtrl').carregarBairros(valor, cidade);
            carregarFretes(cidade);
            $scope.cancelarAlteracao();
            $timeout(function () {
                $scope.selectedIndex = 0;

            }, 10000);
        } else {
            $mdDialog.show(
                    $mdDialog.alert()
                    .clickOutsideToClose(true)
                    .title('O bairro informado já está cadastrado!')
                    .ariaLabel('Existe!')
                    .ok('ok')
                    .targetEvent(event)).then(function () {
            });
        }
    }).error(function (data, status) {
        console.log(data);
    });
};

});

$scope.carregarBairros = function (id_frete, id_cidade) {
    $http.post(url_sistema + 'mostrarcidades/listar_bairros', {'id_frete': id_frete, 'id_cidade': id_cidade}).success(function (data, status, headers, config) {
        $scope.bairros = data;
        console.log(id_cidade);
        if ($scope.bairros.length === 0) {
            $scope.ativo = true;
        } else {
            $scope.ativo = false;
        }
        $timeout(function () {
            Scopes.get('fretesCtrl').bairro(id_cidade);
        }, 3000);
    }).error(function (data, status) { // called asynchronously if an error occurs
        console.log(data);
    });
};

});

print after clicking save

printafterpressingF5

    
asked by anonymous 20.01.2016 / 14:18

1 answer

0

Well, first, as far as I understand, your problem is in executing the second function, since it is in another controller . Although this is possible, I will recommend that you abandon this method!

The function of the controller is only to promote communication between the DOM and the Services (service, factory, directive, etc.). The controller, following the good practice guide, should not be used to load data, send data .. This is the work of services .

The easiest solution - but not the best

Move the function $scope.carregarBairros to the same controller of the other functions.

// --- End --- \

The most correct solution:

Move the requisition tasks to a service (serice or factory-factory is more common to use), we will use factory .

Within it, you define the functions to be performed:

meuModulo.factory('factoryBairro', function($http) { //Não se esqueça de fazer a injeção das dependências aqui
    var service = {
        adicionarBairro:    _adicionarBairro
        /**
         * Adicione aqui somente as funções que podem ser chamadas por um controller, ou um arquivo externo.
         * Se a função a ser chamada, for chamada dentro deste mesmo arquivo, não há necessidade de definir aqui
         */
    };
    return service;

    function _adicionarBairro(bairro, cidade, valor) {
        //Toda a lógica para adicionar o bairro vai aqui;
    };

    function carregarBairros(id_frete, id_cidade) {
        //Toda a lógica para carregar o bairro vai aqui;
    };
});

In this way, you can call services from any controller , just inject factory as a dependency and make the request, like this:

meuModulo.controller('Controller1',function($scope,factoryBairro,...){

And within the controller call the function inside the factory:

$scope.validaForm = function (bairro, cidade) {
    var valor = $("#valor").val();
    if ( /*verificações aqui*/ ) {
        if ($scope.alterar === false) {
            factoryBairro.adicionarBairro(bairro, cidade, valor); //Aqui você chama o serviço
        } else {
            //Restante do código

This will call the adicionarBairro() function that is inside the factory, it will execute $ http, do the checks, etc. And when you are to call the neighborhood loading function, just call the function, without mystery :

function adicionarBairro() {
    //Código anterior
    if (data < 1) {
        $http.post(url_sistema //.. restante do código
        //Mais código aqui

        //Substitua isso:
        Scopes.get('mostrarCidadesCtrl').carregarBairros(valor, cidade);

        //Por isso:
        carregarBairros(valor, cidade);

        //Restante do código
}
function carregarBairros(id_frete, id_cidade) {
    //Lógica da função aqui
}

So, whenever you need to perform this function, do the factory injection in the controller, and then call it.

I recommend you look and read a lot about it. It will greatly help your work, improve the performance of the application, make your code more clean and organized.

Edited:

To get a value created in a factory within a controller, so that you can move to the view, just create a new function, for example:

controller:

$scope.valor = factoryBairro.getData();

factory:

var service = {
    adicionarBairro:    _adicionarBairro,
    getData:            _getData
};
return service;

var minhaData = 'Cidade';

function _getData() {
    return minhaData;
};

Note: If you want the object to maintain a synchronization between the factory and the controller, eg: Updated factory - > Automatically updates the controller. You must use the value to be passed inside an array. Otherwise, the value will not be updated until $digest runs.

At least I do not know another method of synchronizing the data. If anyone knows, please share.

Synchronized example:

var minhaData = {
    'valor';
};

function _getData() {
    return minhaData;
};

function _setData() { //exemplo
    $http.get......
    return minhaData.valor = [
        {id: 1, cidade: 'São Paulo'},
        {id: 2, cidade: 'Rio de Janeiro'},
        //etc...
    ]
};

So your controller is in sync, because you do not rewrite the entire object, just an internal value.

    
20.01.2016 / 16:48