2013-03-17 2 views
2

Я работаю над несколькими файлами, загружающими модуль, и задерживаюсь, когда дело доходит до передачи моего сервиса моему контроллеру без использования $rootScope.Inter-Communication (директива для обслуживания контроллеру)

Директива наблюдает за вводом файла и передает файлы onchange в сервис, где они загружаются и отслеживается процесс загрузки. На основе ответа (от успеха, ошибок и изменений прогресса) родительский контроллер должен показывать большие пальцы и прогресс.

Я не хочу использовать $emit и $on на моем $rootScope, так как мне часто требуется шаблон, и только один родительский контроллер должен знать о загрузках.

Я создал упрощенный (!) Plunkr с дополнительной информацией, чтобы лучше понять проблему.

Есть ли другой способ для моего контроллера реагировать на изменения (происходит внутри фабрики услуг)?
Или, может быть, совсем другой способ достижения такого?

ответ

3

Правильный способ обработки асинхронных операций с помощью углового с помощью promises.

Вы можете вернуть обещание от сервисного вызова и решить его до src большого пальца. Вы могли бы не использовать директиву вообще.

Ваш контроллер будет использовать сервис таким образом:

function ParentController($scope, imageService) { 
    $scope.change = function() { 
    $scope.src = imageService.change(); 

    $scope.then(function(result) { 
     // the loading ended, but there is no need to set the src 
     // as it will already bind to src when ends. 
    }, function(err) { 
     // something went wrong 
    }); 
    }; 
} 

Ваша служба:

app.factory('imageService', function($q, $rootScope) { 

    function doTheUploading(defer) { 
    if (everythingOk) { 
     defer.resolve(thumbSrcString); 
    } else { 
     defer.reject({something: 'an error ocurred'}); 
    } 
    } 

    return { 
    change: function() { 
     // creates the promise 
     var defer = $q.defer(); 
     doSomethingAsync(defer); 
     return defer.promise; 
    } 
    }; 

}); 

По крайней мере, ваш HTML должен выглядеть следующим образом:

<div ng-controller="ParentController"> 
    <img src="{{ src }}"><br><br> 
    <span class="btn" ng-click="change()">Change!</span> 
</div> 

Что касается прогресса, вам нужно будет обратиться с обратными вызовами или вернуть объект, который принесет обещание и прогресс индикатор (то есть: return {promise: defer.promise, percent: 0}). Затем индикатор прогресса должен обновляться внутри службы.

Вы также мог бы приковать свое обещание, если вам нужно какое-либо преобразование в URL возвращенной с сервера до множества его к src собственности, т.м .:

$scope.src = imageService.change().then(function(result) { 
    return 'http://dummyimage.com/' + result; 
    }); 

Обновлено your Plunker.

+0

Большое спасибо за ваш очень подробный ответ :) Я просмотрел API обещаний, но у меня есть один вопрос относительно прогресса: я вернул бы обещание и прогресс только после того, как он будет разрешен или отклонен, не так ли? Это означает, что прогресс составляет либо 100, либо 0. Но 'onprogress' - непрерывное событие. И когда мне нужно использовать '$ emit' для прогресса, не имеет смысла использовать события для всего? –

+0

Идея возвращающегося объекта довольно необычна. Другое решение (я предпочел бы) использовать обратные вызовы. Передача обратного вызова службе ('imageService.change (this.handleOnProgress)') и продолжать звонить ему, чтобы сообщить о прогрессе изнутри службы. В настоящее время я выполняю ['prom.progress'] (https://github.com/kriskowal/q#progress-notification) в Угловых обещаниях, но пока не знаю, будет ли он принят/одобрен, и если он получает одобрение, мы не знаем, когда он будет поставляться в любом случае, поэтому, если вам это нужно вовремя, лучше пойдите с обратным вызовом. –

+0

Приятно, спасибо за вашу помощь :) Надеюсь, он получит одобрение. –

Смежные вопросы