为什么在 AngularJS 指令中弃用了 `replace: true`
Why is `replace: true` Deprecated in AngularJS Directive
我正在使用 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()
事件包含在指令控制器中?
When I create a controller to the directive, and apply $scope.play = function() {};
nothing happens.
您遇到的问题是您使用的 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>'
};
});
来自文档:
replace
([DEPRECATED!], will be removed in next major release - i.e. v2.0)
specify what the template should replace. Defaults to false
.
true
- the template will replace the directive's element.
false
- the template will replace the contents of the directive's element.
-- AngularJS Comprehensive Directive API
来自 GitHub:
Caitp-- It's deprecated because there are known, very silly problems with replace: true
, a number of which can't really be fixed in a reasonable fashion. If you're careful and avoid these problems, then more power to you, but for the benefit of new users, it's easier to just tell them "this will give you a headache, don't do it".
在这种情况下,指令的 isolate 范围与 ng-repeat
指令的 inherited 范围作斗争。因此,要么删除 replace: true
,要么从模板的顶部元素中删除 ng-repeat
。
更新
Note: replace: true
is deprecated and not recommended to use, mainly due to the issues listed here. It has been completely removed in the new Angular.
替换问题:正确
- Attribute values are not merged
- Directives are not deduplicated before compilation
transclude: element
in the replace template root can have unexpected effects
有关详细信息,请参阅 AngularJS $compile Service API Reference - Issues with replace:true
。
我正在使用 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()
事件包含在指令控制器中?
When I create a controller to the directive, and apply
$scope.play = function() {};
nothing happens.
您遇到的问题是您使用的 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>'
};
});
来自文档:
replace
([DEPRECATED!], will be removed in next major release - i.e. v2.0)specify what the template should replace. Defaults to
false
.
true
- the template will replace the directive's element.false
- the template will replace the contents of the directive's element.
-- AngularJS Comprehensive Directive API
来自 GitHub:
Caitp-- It's deprecated because there are known, very silly problems with
replace: true
, a number of which can't really be fixed in a reasonable fashion. If you're careful and avoid these problems, then more power to you, but for the benefit of new users, it's easier to just tell them "this will give you a headache, don't do it".
在这种情况下,指令的 isolate 范围与 ng-repeat
指令的 inherited 范围作斗争。因此,要么删除 replace: true
,要么从模板的顶部元素中删除 ng-repeat
。
更新
Note:
replace: true
is deprecated and not recommended to use, mainly due to the issues listed here. It has been completely removed in the new Angular.
替换问题:正确
- Attribute values are not merged
- Directives are not deduplicated before compilation
transclude: element
in the replace template root can have unexpected effects
有关详细信息,请参阅 AngularJS $compile Service API Reference - Issues with replace:true
。