为什么`replace:true`在AngularJS指令中不推荐使用

问题描述 投票:3回答:1

我正在使用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()事件包含在指令控制器中?

javascript angularjs angularjs-directive soundmanager2
1个回答
2
投票

当我为指令创建一个控制器,并应用$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>'
    };
});

DEMO on JSFiddle

来自Docs:

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

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

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

- AngularJS Comprehensive Directive API

来自GitHub:

Caitp--它已被弃用,因为replace: true存在已知的非常愚蠢的问题,其中一些问题无法以合理的方式得到解决。如果你小心并避免这些问题,那么对你有更多的权力,但为了新用户的利益,更容易告诉他们“这会让你头疼,不要这样做”。

- AngularJS Issue #7636

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


Update

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

替换问题:true

有关更多信息,请参阅AngularJS $compile Service API Reference - Issues with replace:true

© www.soinside.com 2019 - 2024. All rights reserved.