Angular:控制器和指令之间以可测试的方式进行通信?

时间:2014-02-13 06:56:06

标签: javascript angularjs angularjs-directive

我刚刚开始学习Angular,我正在尝试使用它来构建一个文件上传器,它允许我将文件拖到它上面并将它们上传。比较简单。但我不确定如何在我的控制器和我的指令之间进行通信,并且它是可测试的。我的第一个想法是做这样的事情:

angular.module('UploadApp', [])
.controller('UploadController', ['$scope', function($scope) {
    $scope.files = [];

    $scope.$watch('files', function() {
        //TODO: Upload the files somehow, I haven't written the service to do this yet
    }, true);
}])

.directive('UploaderDropzone', function() {
    return {
        restrict: 'A',
        scope: {
            files: '=UploaderFiles'
        },
        link: function(scope, element) {
            function addFile(file) {
                if (file.type && (file.type.indexOf('image/') === 0 ||
                                  file.type.indexOf('video/') === 0)) {

                    scope.$apply(function() {
                        scope.files.push(file);
                    });
                }
            }

            scope.watch('files', function() {
                //TODO: Do something to display the status of the uploads
            }, true);

            element.on('dragenter dragover', function(event) {
                element.addClass('hover');
                event.preventDefault();
            });

            element.on('dragleave drop', function(event) {
                var files = event && ((event.target && event.target.files) || 
                                      (event.dataTransfer && event.dataTransfer.files));

                if (files) {
                    [].forEach.call(files, function(file) {
                        addFile(file);
                    });
                }

                element.removeClass('hover');
                event.preventDefault();
            });
        }
    };
});

然后在模板中:

<div ng-controller="UploadController">
    <div uploader-dropzone uploader-files="files"></div>
</div>

我打算将文件包装在一个对象中,这个对象可以让我将上传进度,成功状态传回给指令等等。但我不知道我将如何测试此代码似乎触发$ watch内的代码会很痛苦?有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

你可以做的是你可以在你的指令中使用ng-model,从你的观点我可以理解你想要捕获的文件值。 代码就像    .directive(&#39; UploaderDropzone&#39;,function(){       返回{         限制:&#39; A&#39;,         范围: {             files:&#39; = UploaderFiles&#39;         },       link:function(scope,element,ngmodel){

或者您可以使用某些服务在两者之间进行通信,如下所示 myModule.directive(&#39; myComponent&#39;,function(mySharedService){     返回{         限制:&#39; E&#39;,         controller:function($ scope,$ attrs,mySharedService){

我找到了上述方法的一个例子,可能会以更好的方式帮助你。试试这个JS代码。

var myModule = angular.module(&#39; myModule&#39;,[]); myModule.factory('mySharedService', function($rootScope) { var sharedService = {};

&#39; sharedService.message =&#39;&#39;;

sharedService.broadcastItem = function() {
    $rootScope.$broadcast('handleBroadcast');
};
myModule.directive('myComponent', function(mySharedService) {
return {


controller: function($scope, $attrs, mySharedService) {
$scope.$on('handleBroadcast', function() {

$ scope.message =&#39;指令:&#39; + mySharedService.message;

});
    },
    replace: true,
    template: '<input>'
};
});
function ControllerZero($scope, sharedService) {
$scope.handleClick = function(msg) {
    sharedService.prepForBroadcast(msg);
};
$scope.$on('handleBroadcast', function() {
    $scope.message = sharedService.message;
});
}