处理父范围单击angular指令

时间:2014-09-23 18:58:59

标签: angularjs angularjs-directive angularjs-scope

我有上传文件的指令。我在我的视图中称之为“UploadRecords.html”。我在“UploadRecords.html”中有一个名为“上传”的按钮。单击此按钮,我想调用我的指令中链接函数内定义的“UploadAll”方法。有什么方法可以达到这个目的。

基本上我想在点击根范围元素时调用指令函数。

注意:我在我的指令中使用了隔离范围

angular.module('fileUpload', [])
.directive(
    "fileUpload",
    function () {
        return ({
            restrict: 'E',
            scope: {                
                onSuccess: '&',
                onError: '&',
            },
            templateUrl: 'Templates/FileUploadTemplate.html',
            link: function (scope, element, attrs) {
                scope.files = [];
                scope.addFile = function (element, documentType) {
                    if (element.files.length > 0) {
                        $.each(element.files, function (index, file) {
                            scope.files.push(file);
                        });
                    }
                    scope.$apply();
                }

                scope.uploadAll = function () {

                    //This is where I upload the files to the web api using a FormData post

                }
            }

        });
    }
    );


<file-upload on-success="onFileUloadAllSuccess()" on-error="onFileUloadAllError()"></file-upload>

<button type="button" class="btn btn-default">Upload All</button>

谢谢, 萨姆。

2 个答案:

答案 0 :(得分:2)

您设置HTML的方式,您的按钮无法与您的指令进行通信,因为它们完全是分开的。您有几个选择:

  1. 移动FileUploadTemplate.html中的按钮,使其现在位于指令范围内。如果您这样做,您只需将ng-click="uploadAll()"添加到属性:

    全部上传

  2. 为您的按钮定义指令。然后使用$emit在两个指令之间进行通信。

  3. 为您的按钮定义指令。定义具有两个子项,按钮和当前模板的“父”指令。这样,两个子节点都可以访问父节点内的范围,并且它们可以通过父节点进行通信。

  4. 以下是$emit的使用方法。将按钮html定义为:

    <button type="button" class="btn btn-default" ng-click="uploadAll()" button-upload>
        Upload All
    </button>
    

    现在为此添加一个指令:

    app.directive('buttonUpload', ['$rootScope', 
        function($rootScope)
        {
            return {
                restrict: 'A',
                link: function(scope, element, attrs)
                {
                    scope.uploadAll = function() {
                        $rootScope.$emit('UPLOAD_ALL');
                    }
                }
            }
        }
    ]);
    

    然后在你的fileUpload指令中,您可以:

    app.directive('fileUpload', ['$rootScope', 
        function($rootScope)
        {
            return {
                // Your restrict, templateUrl, scope
                link: function(scope, element, attrs)
                {
                    // All your other code
                    // remove scope.uploadAll
    
    
                    // This will get called everytime $emit is broadcasted
                    $rootScope.$on('UPLOAD_ALL', function(event) {
                        // Your upload code goes here
                    });
    
                }
            }
        }
    ]);
    

    这不是一个非常好的方法:你不应该真正使用$emit$broadcast。您应该考虑我的第三个选择,即拥有两个指令的父级。

答案 1 :(得分:1)

广播在我看来可以很好地解决您的问题

你可以这样做:

根控制器 - &gt;指令

根控制器

$scope.$broadcast('go');

指令

$scope.$on('go', function () { alert('event is clicked') });

JsFiddle

指令 - &gt;根控制器

Root Controller:

$scope.$on('go', function () { alert('event is clicked') });

指令:

$scope.$emit('go');

**这不一定是最优雅的解决方案,我们同意,但它会解决您的问题