Пользовательский интерфейс не обновляется при изменении списка на угловом контроллере

У меня есть список изображений в моем контроллере, когда я загружаю страницу / контроллер, я вызываю метод для заполнения этого списка, и затем результат списка отображается на интерфейсе интерфейса пользователя через шаблон директивы, когда я обновляю список в контроллере, ответом $http resquest (тот же метод, который работает при первой загрузке) пользовательский интерфейс не отражает изменения списка в контроллере. Я выполняю некоторые поиски в Интернете, и наиболее часто выполняемые инструкции - это ссылка $scope.$apply, o попытаться используйте это при атрибуции списка, но получите ошибку, дайджест уже выполняется. Если я нажимаю на кнопку обновления браузера, все работает нормально. Но кто-то говорит, что это не очень хорошая практика, используйте $scoep.$apply, но я не не представляю, что не так с кодом. Я пытаюсь использовать $timeout, но не работает.

$ scope.listaImagens = resp.data;

angular.module('appImages').controller('HomeCtrl', function($scope, $location, $state, $notification, FileUploader, UrlService, $http, blockUI, ContextoService) {

            //List of images
            $scope.listaImagens = [];


            $scope.findAllImagens = function() {

                var urlImagensPagUsuario = $scope.urlImagem + "/findAllPaginadoByUsuario/" +
                    paginacaoDTO.pagRecordIndex + "/" + paginacaoDTO.pagBatchRecords + "/" + idUsuarioLocal;

                $http.get(urlImagensPagUsuario).then(function(resp) {

                    //HERE, receive the values, but not reflect on UI
                    $scope.listaImagens = resp.data;


                }, function(err) {
                    console.log(err);
                });

            }

            //Busca as imagens
            $scope.findAllImagens();


            //Salva o usuario de contexto selecionado
            $scope.devePersistirUsuarioContexto = function(newUsuario) {

                if (newUsuario && newUsuario.idUsuario) {

                    $scope.urlUsuarioSelecionado = UrlService.makeUrl('usuarioselecionado');
                    var usuarioNew = {
                        "idUsuarioFk": newUsuario.idUsuario
                    };
                    $http.put($scope.urlUsuarioSelecionado, usuarioNew)
                        .then(function(resp) {
                            console.log('usuario de contexto atualizado');
                            $scope.findAllImagens();

                        }, function(err) {
                            console.log(err);
                        });
                }

            }

        }

я пытаюсь это примеры:

        $timeout(function() {
            $scope.listaImagens = resp.data;
        }, 0);

        $timeout(function() {
            $scope.listaImagens = resp.data;
            $scope.$digest()
        }, 0);

        $timeout(function() {
            $scope.$apply(function(){
            $scope.listaImagens = resp.data;
            }
        }, 0);

       scope.$parent.$watch('selecionado', function() {
            if (scope.changeItemDrop) {
                scope.changeItemDrop(scope.selecionado);
            }
        }, true);   

       scope.$watch('selecionado', function() {
            if (scope.changeItemDrop) {
                scope.changeItemDrop(scope.selecionado);
            }
        }, true);   

директивная декларация

<div class="floating-menu-paciente">
        <drop-down-combo placeholder="Escolha o paciente..." url="paciente" selecionado="pacienteContexto" fieldtext="pacienteNome" id="pacienteContexto" change-item-drop="devePersistirPacienteContexto(pacienteContexto)" />
    </div>

diretive

angular.module('appTmw').directive('dropDownCombo', ['UrlService', '$http', function(UrlService, $http, $timeout) {
                return {
                    restrict: 'E', //Diretiva restrita ao elemento
                    scope: {
                        placeholder: "@",
                        url: "@",
                        selecionado: "=",
                        fieldtext: "@",
                        changeItemDrop: "&"
                    },
                    templateUrl: '/assets/templates/dropDownCombo.html',
                    link: function(scope, elm, attrs) {

                        //Quando clica no item para escolha
                        scope.selectItem = function(resultado) {
                            scope.selecionado = resultado;
                            scope.showDrop = false;
                        };

                        scope.$watch('selecionado', function() {
                            if (scope.changeItemDrop) {
                                scope.changeItemDrop(scope.selecionado);
                            }
                        });

                    }
                };

шаблон директивы

<div>
    <div class="combo">
        <input type="text" value={{selecionado[fieldtext].trim()}} placeholder="{{placeholder}}" ng-click="show()" ng-focus="true"> </input>
        <button type="button" class="btn btn-default srcCombo" ng-click="show()">
            <span class="glyphicon glyphicon-search" aria-hidden="true"></span>
        </button>
    </div>
    <!-- "showDrop" variável booleana da diretiva -->
    <div class="listagemCombo" ng-show="showDrop" ng-mouseleave="perdeuFoco()">
        <table>
            <tr ng-repeat="resultado in resultados" ng-click="selectItem(resultado)">
                <td> {{resultado[fieldtext]}} </td>
            </tr>
        </table>
    </div>
</div>

1 ответ

Попробуйте использовать $timeout в put обработчик, то есть:

$http.put($scope.urlUsuarioSelecionado, usuarioNew)
                    .then(function(resp) {
                        console.log('usuario de contexto atualizado');
                        $timeout(function() {
                            $scope.findAllImagens();
                        }, 0);
                    }, function(err) {
                        console.log(err);
                    });

Или просто попробуйте использовать evalAsync который кажется потенциальным решением для вашего случая:

    $http.put($scope.urlUsuarioSelecionado, usuarioNew)
                    .then(function(resp) {
                        console.log('usuario de contexto atualizado');
                        $scope.$evalAsync(function() {
                            $scope.findAllImagens();
                        });
                    }, function(err) {
                        console.log(err);
                    });

Если у вас есть $watch, запускающее событие, и по какой-то причине оно не вызывает функцию, которую вы хотите вызвать, вы можете использовать $rootScope.$broadcast чтобы вызвать это:

// in your $watch
scope.$watch('myVar', function() {
    $rootscope.$broadcast('myEvent');
});

// in your controller
$scope.$on('myEvent', function() {
    $scope.findAllImagens();
});
Другие вопросы по тегам