【问题标题】:Why won't $compile work with service using a directive?为什么 $compile 不能使用指令与服务一起工作?
【发布时间】:2017-05-22 14:42:34
【问题描述】:

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

在此示例中如果您单击指令链接,它不会编译模板,而是将其显示为“{{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();
        };
    }])
<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>

我的问题是为什么 template 不与指令一起编译? (但它在控制器中)

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

附注这是 jsbin 链接,以防您想玩弄代码: http://jsbin.com/vuzutipedu/edit?html,js,output

【问题讨论】:

  • 试试这个方法:element.bind('click', function() { ... });
  • 默认显示什么值?在点击锚标签之前?
  • 这种技术是否真正用于运行 Angular 1.2 的应用程序中?那是一个 3 年的旧版本,许多新的角度技术在该版本中不起作用。相反,一些 1.2 中必需的东西在当前版本中不需要。
  • @AvneshShakya 添加bind 无效。它仍然不起作用:/
  • @Mr_Perfect 如果默认添加,它会显示正确的值“2”。仅在使用指令时,它不起作用..

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


【解决方案1】:

指令需要做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

有关详细信息,请参阅

演示

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="//unpkg.com/jquery"></script>
<script src="//unpkg.com/angular/angular.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>

【讨论】:

  • 非常感谢。这么简单的事情,我浪费了很多时间试图弄清楚。太奇怪了,我从来没有想过这件事。你真的拯救了这一天!
【解决方案2】:

$get 中试试这个,而不是$compile(template)($rootScope)

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

让我知道它是否有效

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-07
    • 2010-10-28
    • 2021-04-29
    • 2015-03-16
    • 1970-01-01
    • 2021-06-07
    相关资源
    最近更新 更多