我有一个 Angular 指令,它实现了本质上是自定义组合框的功能。单击输入控件会导致另一个 div 出现在其下方,并显示模型对象中包含的 div 的列表。您可以在输入控件中键入文本,它会过滤其下方的 div 列表。
我有一些单独的按钮对象(不是指令的一部分,但在同一范围内),它们调用 $scope.clearFilter() 或 $scope.unselectAll() 等方法,而这些方法又调用directiveScope.clearFilter () 或directiveScope.unselectAl()。 DirectiveScope 是组合框指令和主 Controller 之间的共享对象。它使 Controller 能够直接调用指令上的方法。
我整理了一个小Plunker展示我目前的做法。这是一个“本着精神”类型的示例,而不是我的确切代码(许可证问题)。
// HTML
<my-directive sharedobj="myDirective1"></my-directive>
<input type="button" ng-click="clearFilterText1()" value="Clear"/><br/><br/>
// JS
var app = angular.module( 'Test', [] );
app.controller( 'MyController', [ '$scope', function( $scope ) {
$scope.myDirective1 = {};
$scope.myDirective2 = {};
$scope.clearFilterText1 = function() {
console.log("Calling directive 1");
$scope.myDirective1.clearFilterText();
}
$scope.clearFilterText2 = function() {
console.log("Calling directive 2");
// QUESTION: If calling this directive method is bad practice, what is
// equivalent good practice?
$scope.myDirective2.clearFilterText();
}
}]);
app.directive( 'myDirective', function() {
return {
template: "<div><input type='text' ng-model='filterText'/></div>",
scope: {
sharedobj: "="
},
restrict: 'E',
replace: true,
link: function( scope, elem, attrs ) {
// This is the text that the directive will show, and it is conceptually private
// to the directive, so I'd rather not put this into the controller scope.
scope.filterText = "filter this!";
// This method is on the "sharedobj" that is linked into the controller.
// The controller is able to call this method directly, which updates
// the view state. This simply updates "view state".
scope.sharedobj.clearFilterText = function() {
console.log("Setting filter text!");
scope.filterText = "";
}
}
};
});
有人告诉我,让 Angular Controller 直接调用指令上的方法并不是好的设计,但根据Wikipedia's page on MVC :
A controller can send commands to the model to update the model's state (e.g., editing a document). It can also send commands to its associated view to change the view's presentation of the model (e.g., by scrolling through a document).
如果“发送命令”与“调用函数”同义,并且如果您将指令视为“ View ”,那么这听起来正是我正在做的事情,因为指令本质上是 HTML 的扩展。
我看过 StackOverflow 帖子,如 this one这也表明这是一个坏主意(没有理由证明该立场),但建议的替代方案是实现一个单独的服务来处理这种状态,这似乎是一个不必要的复杂解决方案,特别是因为我有这些组合框指令的多个实例。您最终会得到一个甚至不知道自己的 View 状态的指令,这看起来非常错误。
我不明白为什么调用 SomeService.clearFilter()(然后设置指令必须 $watch() 执行的一些“状态”)比仅仅调用 someDirective.clearFilter() 并避免所有开销更好。 Controller 仍然需要了解如何清除过滤器。它只需注入(inject) SomeService 而不是连接到指令。
所以,Angular/MVC 专家,请告诉我为什么这是错误的(或者为什么可以)! :-)
谢谢。
最佳答案
看到这一点的简单方法是指令被认为是独立的或添加行为。当您通过 Controller 调用它们的函数时,您实际上是在使指令依赖于该 Controller 的存在,而不是像它可以/应该那样可重用。
还有其他方法可以实现相同的结果,而无需将 viewController 耦合到指令,但这取决于每种具体情况,因此如果没有更多信息,我无法帮助您:(
干杯
关于javascript - Angular Controller 调用指令上的函数是 'bad practice' 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25560014/