restrict: "A" terminal: true priority: 1-6ren">
gpt4 book ai didi

javascript - 如何创建一个指令,根据条件在目标元素上添加 ng-class 和 ng-disabled?

转载 作者:数据小太阳 更新时间:2023-10-29 05:23:02 24 4
gpt4 key购买 nike

我有以下代码:

app.directive "ngDisableOnVar", ($compile) ->
restrict: "A"
terminal: true
priority: 1000
replace:false
scope: {}
compile: compile = (element, attrs) ->
cattr = attrs["ngDisableOnVar"]
element.attr("ng-class", "{'disabled': !#{cattr}}")
element.attr("ng-disabled", "!#{cattr}")
element.removeAttr("ng-disable-on-var")
pre: preLink = (scope, iElement, iAttrs, controller) ->

post: postLink = (scope, iElement, iAttrs, controller) ->
$compile(iElement)(scope)

我试图将代码基于给定的答案 here .基本上,我想要以下内容:

<input ngDisableOnVar="someScopeVariable>

并将其替换为以下内容:

<input ng-class="{'disabled': !someScopeVariable}" ng-disabled="!someScopeVariable">

出了点问题,因为即使我将它们应用于我的元素,它们也始终处于禁用状态,即使范围变量的计算结果为真。我做错了什么?

编辑:我创建了一个 plunker,其中前 2 个按钮是使用 ng-class 和 ng-disabled 创建的,其他 2 个按钮应该通过使用指令对它们应用相同的东西。

这是具有共享范围的 plunker 版本:http://plnkr.co/edit/TebCQL20ubh5AgJ6nMIl?p=preview

这是没有共享范围的:http://plnkr.co/edit/CPm55MrHA8z6Bx4GbxoN?p=preview

问题是,没有共享范围的不会更新。我怎样才能使它们更新,并使条件取决于作为参数传递的变量?

编辑#2:我开始相信范围共享是这两个按钮应该起作用的正确方式,而不是创建一个将两个按钮封装在其中的新指令。虽然不能 100% 确定。

最佳答案

我会同意您的编辑#2,因为它们是相关的。如果我们将它们创建为单独的元素,我们需要以某种方式将相关元素传递给每个元素 => 当我们单击 1 个按钮时,我们会更新自身以及相关元素。

我在这里修改了您的第一种方法以使其起作用:http://plnkr.co/edit/KgYIlATiw9xzTEZt9Jv1?p=preview

在这个例子中,我必须将相关元素传递给每个指令,这样当我们点击时我们可以更新自身和相关元素:

related-element="btnForward"

我在指令中做了一些修改:

scope: {
reactOn: "=", //use property binding instead of function binding
relatedElement:"@"
},
link: function(scope, element, attrs) {
scope.toggle = function(){
scope.reactOn = !scope.reactOn;//toggle current element
var relatedScope = $("#"+scope.relatedElement).scope();//get related element's scope and toggle it
relatedScope.reactOn = !relatedScope.reactOn;
}
//var cattr = attrs.ngDisableReactOn;
element.attr("ng-class", "{'disabled': !reactOn}"); //Use reactOn instead as this is the property of current scope
element.attr("ng-disabled", "!reactOn");
element.attr("ng-click", "toggle()");
element.removeAttr("ng-disable-react-on");
$compile(element)(scope);
}

我们不需要让事情变得复杂。只需创建一个普通指令来包裹 2 个按钮。

myApp.directive("ngDisableReactOn", function($compile) {
return {
restrict: "A",
templateUrl:"ngDisableReactOn.html",
scope: {
can_go_back: "@"
},
link: function(scope, element, attrs) {
scope.goBack = function(){
scope.can_go_back = false;
}

scope.goFwd = function(){
scope.can_go_back = true;
}
}
}
});

模板:

<input type="button" value="go back" ng-click="goBack()"  ng-class="{'disabled': !can_go_back}" ng-disabled="!can_go_back">
<input type="button" value="go fwd" ng-click="goFwd()" ng-class="{'disabled': can_go_back}" ng-disabled="can_go_back">

DEMO

另一种解决方案是创建父指令作为容器。这是我最喜欢的解决方案。使用这种方法,您可以自由更改指令的内部内容,例如添加更多按钮、更多文本……(不需要对模板进行硬编码)父指令用作管理器确保一次只有 1 个活跃的 child :

myApp.directive("ngDisableReactOnContainer", function() { //Container directive to manage all child directives
return {
restrict: 'EA',
replace: true,
transclude: true,//Use transclusion to move inner content to the template
template: '<div ng-transclude></div>',
controller: function() {
var children = [];
this.selectChild = function(activeChild) { //ensure that only 1 child is active at a time
activeChild.active = true;
angular.forEach(children, function(child) {
if (child != activeChild) {
child.active = false;
}
});
}

this.addChild = function(child) {
children.push(child);
}
}
};
});

myApp.directive("ngDisableReactOn", function($compile) {
return {
restrict: "A",

scope:{
active:"@"
},

require: '^?ngDisableReactOnContainer',
link: function(scope, element, attrs, controller) {

scope.active = scope.active === 'true';

controller.addChild(scope);//register itself with the container

scope.select = function(){//When this element is clicked, inform the container to toggle all children accordingly.
controller.selectChild(scope);
}

//Add ng-class and ng-disabled based on your requirement.
element.attr("ng-class", "{'disabled': active}"); //Use active instead as this is the property of current scope
element.attr("ng-disabled", "active");
element.attr("ng-click", "select()");
element.removeAttr("ng-disable-react-on");
$compile(element)(scope);
}
}
});

使用这些指令很简单:

<div ng-disable-react-on-container>
<input ng-disable-react-on type="button" value="button 1" active="true" >
<input ng-disable-react-on type="button" value="button 2" >
<input ng-disable-react-on type="button" value="button 3" >
</div>

DEMO

关于javascript - 如何创建一个指令,根据条件在目标元素上添加 ng-class 和 ng-disabled?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21484641/

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