为什么使用指令不会使用服务进行编译?

时间:2017-01-08 04:06:09

标签: javascript angularjs angularjs-directive angularjs-service angularjs-compile

请看一下这个例子,因为这是解释问题的最佳方法。

在此示例中,如果单击指令链接,则不会编译模板,而是将其显示为" {{1 + 1}}"

另一方面,如果您点击"简单链接"它编译模板并显示" 2"代替



angular.module('myApp', [])
    .provider('$popup', function() {
        var service = {};

        this.$get = ['$compile', '$rootScope', function($compile, $rootScope) {
            var template = $('<div>{{1+1}}</div>');
            service.go = function() {
                $(document.body).append(template);
                $compile(template)($rootScope);
            }
            return service;
        }];
    })
    .directive('popupLink', ['$popup', function($popup) {
        return {
            restrict: 'A',
            scope: {},
            link: function link(scope, element, attrs) {
                element.click(function() {
                    $popup.go();
                    return false;
                });
            }
        };
    }])
    .controller('mainCtrl', ['$scope', '$popup', function($scope, $popup) {
        $scope.go = function() {
            $popup.go();
        };
    }])
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>

<div ng-app="myApp" ng-controller="mainCtrl">
    <a ng-href="/test" popup-link>Directive link</a>
    <a href="#" ng-click="go()">Simple link</a>
</div>
&#13;
&#13;
&#13;

我的问题是,template编译指令的原因是什么? (但在控制器中确实如此)

我如何修复它以便它也在指令中编译?

P.S。这是jsbin链接,以防您想要使用代码: http://jsbin.com/vuzutipedu/edit?html,js,output

2 个答案:

答案 0 :(得分:3)

指令需要scope.$apply();

link: function link(scope, element, attrs) {
    element.click(function() {
        $popup.go();
        //ADD apply
        scope.$apply();
        return false;
    });

click事件处理程序在AngularJS框架之外执行。需要执行框架摘要周期来执行{{1+1}}插值的观察器。

它适用于ng-click指令,因为该指令包含scope.$apply

- AngularJS Developer Guide (v1.1) - Concepts - Runtime

angular.module('myApp', [])
    .provider('$popup', function() {
        var service = {};

        this.$get = ['$compile', '$rootScope', function($compile, $rootScope) {
            var template = $('<div>{{1+1}}</div>');
            service.go = function() {
                $(document.body).append(template);
                $compile(template)($rootScope);
            }
            return service;
        }];
    })
    .directive('popupLink', ['$popup', function($popup) {
        return {
            restrict: 'A',
            scope: {},
            link: function link(scope, element, attrs) {
                element.click(function() {
                    $popup.go();
                  //ADD apply
                    scope.$apply();
                    return false;
                });
            }
        };
    }])
    .controller('mainCtrl', ['$scope', '$popup', function($scope, $popup) {
        $scope.go = function() {
            $popup.go();
        };
    }])
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>

<div ng-app="myApp" ng-controller="mainCtrl">
    <a ng-href="/test" popup-link>Directive link</a>
    <a href="#" ng-click="go()">Simple link</a>
</div>

答案 1 :(得分:0)

$get中尝试此操作,而不是$compile(template)($rootScope)

$compile(angular.element(template))(angular.element(template).scope());

让我知道它是否有效