为什么“替换:真”在 AngularJS 指令中被弃用

Why is `replace: true` Deprecated in AngularJS Directive

本文关键字:指令 AngularJS 替换 为什么      更新时间:2023-09-26

我正在使用 angularjs 开发一个示例播放器,使用元素指令。我希望指令模板中的事件保留在指令中。换句话说,如何使用指令中的控制器来创建范围仅为指令模板中的元素的事件。

该指令:

logsApp.directive('logPlayer', function() {
    return {
        restrict: 'E',
        replace: true,
        scope: {audio: '='},
        template: '<div ng-repeat="sample in audio">' +
            '{{sample.title}}' +
            '<button type="button" class="btn btn-default" ng-click="play()">Play</button>' +
            '<button type="button" class="btn btn-danger" ng-click="stop()">Stop</button>' +
            '</div>'
    };
});

我可以让 ng-click 事件工作的唯一方法是将事件方法放在父控制器的$scope中:

logsApp.controller('LogListController', ['$scope', '$rootScope', 'LogsService', 'SoundManager', function($scope, $rootScope, LogsService, SoundManager) {
    ...
    $scope.play = function() {
    SoundManager.sound.createSound({
        id: SoundManager.idPrefix + this.sample.id,
        url: this.sample.filename,
        autoLoad: true,
        autoPlay: false,
        onload: function() {
            this.setPosition(0);
            this.play({
                whileplaying: function() {
                    ...
                }
            });
        }
    });
};
$scope.stop = function() {
    SoundManager.sound.stopAll();
};

如何完成将play()stop()事件包含在指令控制器中?

当我为指令创建一个控制器并应用$scope.play = function() {};没有任何反应时。

遇到的问题是您正在使用已弃用的replace: true。删除它,指令的控制器将看到单击事件。

angular.module("myApp").directive('logPlayer', function() {
    return {
        restrict: 'E',
        //replace: true,
        scope: {audio: '='},
        controller: function($scope) {
            $scope.play = function(index) {
                console.log("play clicked "+index);
            };
        },
        template: '<div ng-repeat="sample in audio">' +
        '{{sample.title}}' +
        '<button type="button" ng-click="play($index)">Play</button>' +
        '<button type="button" ng-click="stop($index)">Stop</button>' +
        '</div>'
    };
});

JSFiddle上的演示。

从文档中:

replace([已弃用!],将在下一个主要版本中删除 - 即v2.0)

指定模板应替换的内容。默认为 false

  • true - 模板将替换指令的元素。
  • false - 模板将替换指令元素的内容。

-- AngularJS Comprehensive Directive API

从 GitHub:

Caitp--它已被弃用,因为replace: true存在已知的,非常愚蠢的问题,其中许多问题无法以合理的方式真正修复。如果你小心翼翼地避免这些问题,那么你就会有更多的权力,但为了新用户的利益,更容易告诉他们"这会让你头疼,不要这样做"。

-- AngularJS 问题 #7636

在这种情况下,指令的隔离作用域正在与ng-repeat指令的继承作用域作斗争。因此,要么删除replace: true,要么从模板的顶部元素中删除ng-repeat

<小时 />

更新

注意:replace: true已弃用,不建议使用,主要是由于此处列出的问题。它已在新的角度中完全删除。

替换问题:true

  • 属性值未合并
  • 指令在编译前不删除重复
  • 数据
  • 替换模板根目录中的transclude: element可能会产生意外效果

有关详细信息,请参阅 AngularJS $compile服务 API 参考 - replace:true问题 。