【问题标题】:AngularJS: strange behavior on templateUrl in directive(template works well)AngularJS:指令中templateUrl的奇怪行为(模板效果很好)
【发布时间】:2016-07-18 14:10:05
【问题描述】:

我有两个指令,一个是表格,另一个是按钮。
但是当我在按钮指令中使用 templateUrl 时,所有按钮都显示在表格的同一行中。
但是“模板”可以很好地工作。
有人可以帮忙吗?

这两个 Demo 的 plunker 如下:
http://plnkr.co/edit/9EaRfrSQggPETrXhNZvq?p=preview : using templateUrl
http://plnkr.co/edit/UHzEpugxtM6JjoNrUd9X?p=preview : using template

指令 myButton1 和 myButton2 之间的唯一区别是:
myButton1 使用 :
templateUrl: function (element, attrs) {
返回 TEMPLATE_ACTION;
}
“actionTemplate.html”的内容是:

<div ng-if="config !== undefined">b</div><br/><br/>

myButton2 使用:
模板:'&lt;div ng-if="config !== undefined"&gt;b&lt;/div&gt;',

    angular.module('myApp', [])
            .controller('MyController', ['$scope', function ($scope) {
                $scope.data = [
                    {name: 'field1', config: {type: 'config1'}},
                    {name: 'field2', config: {type: 'config2'}}
                ];
            }])
            .directive('myGrid', ['$compile', function($compile) {
                return {
                    restrict: 'E',
                    replace: true,
                    template: '' +
                        '<table>' +
                        '<tbody>' +
                        '<tr ng-repeat="item in data">' +
                        '    <td><div><my-button2 config="item.config"></my-button2></div></td>' +
                        '    <td>{{item.name}}</td>' +
                        '</tr>' +
                        '</tbody>' +
                        '</table>',
                    scope: true
                }
                }])
            .directive("myButton1", ["$compile",
                function ($compilee) {
                    var TEMPLATE_ACTION = 'views/actionTemplate.html';
                    return {
                        restrict: "E",
                        replace: true,
                        scope: true,
                        templateUrl: function (element, attrs) {
                            return TEMPLATE_ACTION;
                        },
                        link: function (scope, iElement, iAttrs) {
                            var config = scope.$eval(iAttrs.config);
                            scope.config = config;
                        }
                    };
                }
            ])
    ;

结果是两个按钮显示在同一行,如下图:

但是在指令中使用“模板”,效果很好:

        angular.module('myApp', [])
            .controller('MyController', ['$scope', function ($scope) {
                $scope.data = [
                    {name: 'field1', config: {type: 'config1'}},
                    {name: 'field2', config: {type: 'config2'}}
                ];
            }])
            .directive('myGrid', ['$compile', function($compile) {
                return {
                    restrict: 'E',
                    replace: true,
                    template: '' +
                        '<table>' +
                        '<tbody>' +
                        '<tr ng-repeat="item in data">' +
                        '    <td><div><my-button2 config="item.config"></my-button2></div></td>' +
                        '    <td>{{item.name}}</td>' +
                        '</tr>' +
                        '</tbody>' +
                        '</table>',
                    scope: true
                }
                }])
            .directive("myButton2", ["$compile",
                function ($compilee) {
                    return {
                        restrict: "E",
                        replace: true,
                        scope: true,
                        template: '<div ng-if="config !== undefined">b</div>',
                        link: function (scope, iElement, iAttrs) {
                            var config = scope.$eval(iAttrs.config);
                            scope.config = config;
                        }
                    };
                }
            ])
    ;

结果如下:

【问题讨论】:

  • 你能创建一个小提琴来显示这个问题吗?正如你所描述的,我自己创建了一个,但结果没有什么不同。 actionTemplate.html可能有问题
  • plunker 已创建供您参考:plnkr.co/edit/9EaRfrSQggPETrXhNZvq?p=preview

标签: angularjs templates directive


【解决方案1】:

在同时使用ng-repeattemplateUrlng-ifreplace:true 时可能存在一个已知问题,尽管据说已修复多次。

可能是角度内部的transclude 逻辑存在问题。

ng-ifng-repeat是angular中的两个特殊指令,同时templateUrl中的DOM被异步加载并暂停编译。这种复杂的情况会以某种方式产生问题。

为避免这种情况,只需使用ng-show 代替ng-if,或使用template 代替templateUrl,或者为templateUrl 设置一个脚本模板以将其放入$templateCache

已知问题参考(或者你可以自己google更多)

https://github.com/angular/angular.js/issues/14326https://github.com/angular/angular.js/issues/11855https://github.com/angular/angular.js/issues/7183

【讨论】:

  • 谢谢大佬,我试过templateUrl,template,replace,发现下面的方法可以解决这个问题:删除“replace:true”并添加“trunsclude:true”。对此有什么想法吗?
猜你喜欢
  • 2013-06-22
  • 2013-07-03
  • 2014-11-11
  • 1970-01-01
  • 2017-09-06
  • 2016-04-24
  • 2013-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多