【发布时间】:2014-10-22 23:27:59
【问题描述】:
我有一个 Angular 指令,它实现了本质上是一个自定义组合框。单击输入控件会导致另一个 div 出现在其下方,并显示模型对象中包含的 div 列表。您可以在输入控件中键入文本,它会过滤其下方的 div 列表。
我有几个单独的按钮对象(不是指令的一部分,但在同一范围内)调用诸如 $scope.clearFilter() 或 $scope.unselectAll() 之类的方法,而这些方法又调用了 directiveScope.clearFilter () 或directiveScope.unselectAl()。 directiveScope 是组合框指令和主控制器之间的共享对象。它使控制器能够直接调用指令上的方法。
我整理了一个小的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 控制器直接调用指令上的方法不是好的设计,但根据Wikipedia's page on MVC:
控制器可以向模型发送命令以更新模型的状态(例如, 编辑文档)。 它还可以向其关联视图发送命令 更改模型的视图表示(例如,通过滚动 通过文件)。
如果“发送命令”与“调用函数”同义,并且如果您将指令视为“视图”,我会这样做,这听起来就像我正在做的事情,因为指令本质上是 HTML 的扩展。
我已经看到 StackOverflow 的帖子,例如 this one,这也表明这是一个坏主意(没有理由证明该立场),但实施单独服务来处理这种状态的推荐替代方案似乎是一个不必要的复杂解决方案,尤其是因为我有这些组合框指令的多个实例。你最终会得到一个甚至不知道自己的视图状态的指令,这看起来非常错误。
我不明白为什么调用 SomeService.clearFilter(),然后设置一些指令必须 $watch() 的“状态”,比仅仅调用 someDirective.clearFilter() 并避免所有开销要好。控制器仍然必须知道清除过滤器。它只需要注入 SomeService 而不是连接到指令。
所以,Angular/MVC 专家,请告诉我为什么这是错误的(或者为什么没问题)! :-)
谢谢。
【问题讨论】:
-
MVC 是一个 .. 存储桶术语。考虑 Angular(就像 KO 和 Kendo 一样)基于声明式可观察模型工作;这意味着bucket-term语句需要在上下文中进一步应用。
-
无论如何,不要问“这是好还是坏的做法......”问题(然后为他们辩护),只需询问概述情况的给定任务 -为什么使用当前方法以及与之相关的问题/问题是什么。
-
user2864740:我采取的方法“有效”。 “问题/问题”来自代码审查,其中一位同事认为如果没有控制器到指令的函数调用,设计会更好,并认为这很“奇怪”。此外,任何关于好/坏做法的讨论都必然涉及描述为什么一种方法比另一种更好(也称为“捍卫”它),并且通常需要权衡取舍。
标签: javascript angularjs model-view-controller controller angularjs-directive