在执行控制器之前,让AngularJS编译指令和链接函数

时间:2014-01-04 13:37:19

标签: angularjs hyperlink angularjs-directive angularjs-scope

由于我的程序的性质,我要求将函数放在作用域上并在指令的链接函数和控制器之间共享,就像这样..

.controller("controller", function($scope, $location, $timeout, model) {

    //irrelevant code

    $scope.addObject(draggables[i]);

};


.directive("designCanvas", function($timeout) {
    return {
        restrict: "A",
        link: function($scope, element) {

            $scope.addObject = function(draggable) {

                // irrelevant code
            }
        }
    }
}

当我调用此函数时,我得到' $ scope.addObject不是函数'。

我的问题是在angularJS评估了链接函数之前控制器正在执行,因为当我使用$ timeout将函数调用延迟几秒时,函数调用正常工作

所以我的问题是,如何才能首先编译链接函数的内容?

3 个答案:

答案 0 :(得分:1)

我建议将此功能作为服务编写,并将服务注入指令和控制器。 共享功能应作为服务实施。

.factory("objectService",function(){
    return {
       addObject : function (draggable){
          //your code of this function
       }
    };
});

.controller("controller", function($scope, $location, $timeout, model,objectService) {

    //irrelevant code

    $scope.addObject = function (draggable){
        objectService.addObject(draggable); //reuse this function
       //objectService.addObject.call($scope,draggable) if you want to call this function with $scope as the context.
    };
};

.directive("designCanvas", function($timeout,objectService) {
    return {
        restrict: "A",
        link: function($scope, element) {
            $scope.addObject = function(draggable) {
                objectService.addObject(draggable); //reuse this function.
                //objectService.addObject.call($scope,draggable) if you want to call this function with $scope as the context.

                //write more logic specific to this function, like modifying link's local data.
            }
        }
    }
}

答案 1 :(得分:0)

我会在控制器中创建$watch来监听指令中的某些标志。

类似的东西:

.controller("controller", function($scope, $location, $timeout, model) {

    //irrelevant code
    $scope.flag = false; 

     $scope.$watch(function () {
        return $scope.flag;
    },
    function (newValue, oldValue) {
        if(newValue == true){
            $scope.addObject(draggables[i]);
         }
    }, true);


};


.directive("designCanvas", function($timeout) {
    return {
        restrict: "A",
        link: function($scope, element) {
            $scope.flag = true;
            $scope.addObject = function(draggable) {

                // irrelevant code
            }
        }
    }
}

这有点乱,但我认为这是一个方向。相反$scope.flag您可以尝试使用回调,如:

 .controller("controller", function($scope, $location, $timeout, model) {

     $scope.callback= function() {
       $scope.addObject(draggables[i]);
     }
    };

.directive("designCanvas", function($timeout) {
        return {
            restrict: "A",
            link: function($scope, element) {

                $scope.addObject = function(draggable) {

                  // ....

                  $scope.callback();
                }
            }
        }
    }

希望它会有所帮助,

答案 2 :(得分:0)

我会创建另一个指令并使其依赖于designCanvas

.directive("designCanvas", function() {
    return {
        controller: function() {
            this.addObject = function(draggable) {
                alert(draggable.name);
            }
        }
    }
})

.directive("draggable", function() {
    return {
        require: '^designCanvas',
        link: function(scope, element, attrs, designCanvasController) {
            designCanvasController.addObject(scope.item);
        }
    }
});

使用类似这样的东西:

<div design-canvas>
    <div ng-repeat="item in draggables" draggable>{{item.name}}</div>     
</div>

演示plunker

我认为,将指令与控制器联系起来不是最好的主意。你应该选择服务还是一个指令。