【发布时间】:2018-05-20 15:47:05
【问题描述】:
这是一个关于 Angular 1,而不是 Angular 2 的问题。
我的设置有些复杂:我有一个负责特定页面的控制器(控制器 A)。在这个页面上,我有一个自定义指令,它接受从页面上的控制器中提取的输入。然而,这个自定义指令也有它自己的控制器(控制器 B),我通过属性上的绑定将信息传递给它。我传递给这个指令和控制器 B 的大部分信息都是由控制器 A 生成和处理的。
控制器 A 本质上可以描述为控制器 B 的父级。
但是,与控制器 B 的该指令的绑定是双向绑定 (=),因此由于双向绑定,指令中控制器 B 中更改的信息应该冒泡返回并进入控制器 A,并且因为传入的初始属性是控制器 A 的绑定信息。
虽然很复杂,但这对我来说大约 99% 的时间都有效。我想以这种方式禁用页面上有一个按钮:ng-disabled=CtrlA.buttonDisabled()。
buttonDisabled() 是控制器 A 上的一个函数,它从指令中的双向有界值中获取信息到控制器 B,以便返回 true、禁用按钮或 false、不禁用按钮。
在一个特定实例中,即使更改控制器 B 上应该影响此功能的值,该功能本身也不会触发,因此我的按钮在应该禁用时才启用。
我想知道如何强制控制器 A 上的 buttonDisabled() 通过更改控制器 B 内部的值来执行。这可能吗?我可以通过 $watch 做到这一点吗?如果是这样,我应该将这些信息放在哪个控制器?
这是我的代码的一个非常简化的版本:
控制器 A:
$scope.userName = "";
$scope.buttonDisabled = function() {
if($scope.userName){
return false;
}
return true;
};
控制器 B:
$scope.userName = "";
$scope.clearUserName = function(){
$scope.userName = "";
//I want to call disableButton from controller A here
}
主页的 HTML:
<div ng-controller="CtrlA">
<specialDirective username="{{userName}}"></specialDirective>
<button ng-disabled="buttonDisabled()" ></button>
</div>
specialDirective 模板的 HTML
<input ng-model="userName" />
<button ng-click="clearUserName()" ></button>
指令设置:
app.component("specialDirective",{
controller: CtrlB,
bindings: {
userName: "="
},
template: "directiveTemplate.html"
});
userName 在 specialDirective 中是双向绑定的。
由于其他要求,我无法将clearUserName() 或buttonDisabled() 直接移动到另一个控制器中。
编辑:感谢指出我的缺陷的评论者——我已尽我所能在这篇文章和我的回答帖子中纠正它们。我从头开始编写这个例子,因为复制粘贴我的确切代码太复杂了,它不直接使用 $scope 对象等,所以我为我的不正确语法道歉。如果我错过了其他任何内容,请纠正我。 (:
【问题讨论】:
-
在指令的模板中使用
ng-controller指令是不明智的,因为ng-controller添加了一个子作用域。 Instread 使用指令定义对象的controller属性。有关详细信息,请参阅AngularJS Comprehensive Directive API Reference。 -
代码混合了双花括号
{{ }},使用角度表达式进行插值。这是不明智和自问自答的。有关详细信息,请参阅AngularJS Developer Guide - Why mixing interpolation and expressions is bad practice -
最好避免双向绑定,
=。相反,输入应该使用<和@绑定,输出使用&绑定实现。有关详细信息,请参阅AngularJS Developer Guide - Component-based application architecture。 -
对于
<button>元素,开始和结束标记都是强制性的。有关详细信息,请参阅MDN HTML Reference -<button>element。
标签: javascript html angularjs binding angular-directive