gpt4 book ai didi

javascript - AngularJS ngRepeat within Directiving using a locally defined collection

转载 作者:行者123 更新时间:2023-11-29 10:34:32 25 4
gpt4 key购买 nike

我正在尝试弄清楚如何在使用 ngRepeat 的指令中使用本地定义的对象数组 - 我没有为此使用任何 Controller 。

我有一个如下所示的指令模板设置

<div id="radioBtn" class="btn-group env-switcher">
<a
ng-repeat="env in environments" ng-click="setEnv(env)" ng-class="{'active': env.active}"
href="javascript:void(0);" class="btn btn-info btn-sm" >

<i class="fa {{env.icon}}" aria-hidden="true"></i>
&nbsp;&nbsp;{{env.label}}

</a>
</div>

我有我的指令代码

App.directive('envSwitcher', [function(){
return {
restrict: 'C',
link: function($scope, $elem, $attrs){

$scope.activeEnvironment = 'unknown';

$scope.environments = [
{
label: 'Local',
icon: 'fa-hand-o-down',
value: 'local',
active: true
},
{
label: 'Staging',
icon: 'fa-hand-rock-o',
value: 'staging',
active: false
},
{
label: 'Live',
icon: 'fa-hand-o-up',
value: 'live',
active: false
}
];

$scope.setEnv = function(env){

angular.forEach($scope.environments, function(model, key){

if( angular.equals(env, model) ){
model.active = true;
$scope.activeEnvironment = model.value;
}
else {
model.active = false;
}
});
}
}
}
}]);

但是,当您在页面上有多个这样的内容时,$scope 会溢出并更新它们。因此,如果我在 Directive Instance 1 上运行 setEnv 函数,那么 Directive Instance 2 和 3 也会发生变化。

我知道有一个 scope 属性,我试图将其设置为 scope: {} 以隔离它,但是 ngRepeat 没有显示任何 - 我猜是因为我做错了什么。

我将如何实现上述目标?例如,使用本地定义的对象数组,在指令模板中与 ngRepeat 一起使用,没有 $scope 溢出?

谢谢

最佳答案

我假设这是您要避免的当前行为:

function envSwitcher() {
return {
restrict: 'C',
link: function($scope, $elem, $attrs){

$scope.activeEnvironment = 'unknown';

$scope.environments = [
{
label: 'Local',
icon: 'fa-hand-o-down',
value: 'local',
active: true
},
{
label: 'Staging',
icon: 'fa-hand-rock-o',
value: 'staging',
active: false
},
{
label: 'Live',
icon: 'fa-hand-o-up',
value: 'live',
active: false
}
];

$scope.setEnv = function(env){
angular.forEach($scope.environments, function(model, key){

if( angular.equals(env, model) ){
model.active = true;
$scope.activeEnvironment = model.value;
}
else {
model.active = false;
}
});
}
}
}
}

angular.module('myApp', []);
angular
.module('myApp')
.directive('envSwitcher', envSwitcher);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp">
<div id="radioBtn" class="btn-group env-switcher">
<a ng-repeat="env in environments"
ng-click="setEnv(env)"
ng-class="{'active': env.active}"
href=""
class="btn btn-info btn-sm">
{{env.label}}
</a> <span>Active env: {{activeEnvironment}}</span>
</div>
<div id="radioBtn" class="btn-group env-switcher">
<a ng-repeat="env in environments"
ng-click="setEnv(env)"
ng-class="{'active': env.active}"
href=""
class="btn btn-info btn-sm">
{{env.label}}
</a> <span>Active env: {{activeEnvironment}}</span>
</div>
</div>

您在指令之间共享一个范围。如果您希望它们是独立的,则必须将 a link 放在指令的模板中,这将允许隔离范围。

这里我使用了一个类似组件的指令,使用了 controller 而不是 link 因为一个独立的、有状态的指令应该是一个组件。 (而且我不知道您使用的是哪个 Angular 版本,或者是否对您强加了指令)

我还将指令限制为属性,因为使用类指令不是最佳实践。

function envSwitcher() {
return {
restrict: 'A',
scope: {},
template: `
<a ng-repeat="env in ec.environments"
ng-click="ec.setEnv(env)"
ng-class="{'active': env.active}"
href=""
class="btn btn-info btn-sm">
{{env.label}}
</a> <span>Active env: {{ec.activeEnvironment}}</span>
`,
controller: envController,
controllerAs: 'ec'
}
}

function envController() {
var vm = this;
this.activeEnvironment = 'unknown';
this.setEnv = setEnv;
this.environments = [
{
label: 'Local',
icon: 'fa-hand-o-down',
value: 'local',
active: true
},
{
label: 'Staging',
icon: 'fa-hand-rock-o',
value: 'staging',
active: false
},
{
label: 'Live',
icon: 'fa-hand-o-up',
value: 'live',
active: false
}
];

function setEnv(env){
angular.forEach(vm.environments, function(model, key){
if(angular.equals(env, model)){
model.active = true;
vm.activeEnvironment = model.value;
}
else {
model.active = false;
}
});
}
}

angular.module('myApp', []);
angular
.module('myApp')
.directive('envSwitcher', envSwitcher)
.controller('envController', envController);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp">
<div id="radioBtn" env-switcher class="btn-group"></div>
<div id="radioBtn" env-switcher class="btn-group"></div>
</div>

编辑:

为了使您的原始代码只需最少的更改即可工作,您必须在指令模板中复制 div(a href...)的内容,然后您可以添加隔离范围。

function envSwitcher() {
return {
restrict: 'C',
scope: {},
template: `
<a ng-repeat="env in environments"
ng-click="setEnv(env)"
ng-class="{'active': env.active}"
href=""
class="btn btn-info btn-sm">
{{env.label}}
</a> <span>Active env: {{activeEnvironment}}</span>
`,
link: function($scope, $elem, $attrs){

$scope.activeEnvironment = 'unknown';

$scope.environments = [
{
label: 'Local',
icon: 'fa-hand-o-down',
value: 'local',
active: true
},
{
label: 'Staging',
icon: 'fa-hand-rock-o',
value: 'staging',
active: false
},
{
label: 'Live',
icon: 'fa-hand-o-up',
value: 'live',
active: false
}
];

$scope.setEnv = function(env){
angular.forEach($scope.environments, function(model, key){

if( angular.equals(env, model) ){
model.active = true;
$scope.activeEnvironment = model.value;
}
else {
model.active = false;
}
});
}
}
}
}

angular.module('myApp', []);
angular
.module('myApp')
.directive('envSwitcher', envSwitcher);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<div ng-app="myApp">
<div id="radioBtn" class="btn-group env-switcher"></div>
<div id="radioBtn" class="btn-group env-switcher"></div>
</div>

关于javascript - AngularJS ngRepeat within Directiving using a locally defined collection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39121953/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com