我创建了一个组件search-context,效果不错。它是可配置的,而且它做了它应该做的事情。
<search-context context-name="Groups"
compare-columns="['displayName']"
search-manager="$ctrl"
query-url="/group/search/{{contextId}}"
icon="fa fa-users"
on-resolve-item-url="resolveItemUrl(row)"></search-context>
这里是它独立运行的情况。
还有很多其他的搜索上下文,我想创建一个搜索管理组件,这样我就可以写这样的标记。
<search-manager>
<search-context context-name="Devices"
compare-columns="['displayName']"
search-manager="$ctrl"
query-url="/device/search/{{contextId}}"
icon="fa fa-laptop"></search-context>
<search-context context-name="Groups"
compare-columns="['displayName']"
search-manager="$ctrl"
query-url="/group/search/{{contextId}}"
icon="fa fa-users"
on-resolve-item-url="resolveGroupEditUrl(row)"></search-context>
</search-manager>
一般的计划是让搜索上下文检查是否有搜索管理器,如果有,则压制自己的输入按钮控件,搜索管理器将提供输入控件,并向搜索上下文提供搜索词。
AngularJS组件文档中的例子演示了这一点 动态 子控件的模板中使用ng-repeat,但不清楚如何设置来处理我建议的显式标记。如果可能的话,我希望不需要显式地指定 search-manager="$ctrl"
父母参考。
如何去做,必须研究和了解的辅助课题有哪些?只是关键的概念名称会有很大的帮助,但如果能有一个概述和进一步阅读清单就更好了。
我的第一次尝试是在模板的 search-manager
样子
<div>
<div class="panel-heading">
<h3 class="panel-title">Search</h3>
<div class="input-group">
<input class="form-control" ng-model="$ctrl.term" />
<span class="input-group-btn" ng-click="$ctrl.search()">
<button class="btn btn-default">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</div>
<div class="panel-body">
<ng-transclude></ng-transclude>
</div>
</div>
代码是这样的
function SearchManagerController($scope, $element, $attrs, $http) {
var ctrl = this;
ctrl.searchContext = [];
ctrl.registerSearchContext = function (searchContext) {
ctrl.searchContext.push(searchContext);
}
ctrl.search = function () {
ctrl.searchContext.forEach(function (searchContext) {
searchContext.search(ctrl.term);
});
};
}
angular.module("app").component("searchManager", {
templateUrl: "/app/components/search-manager.html",
controller: SearchManagerController,
transclude: true,
bindings: {
term: "@"
}
});
子组件被包含在内,但它们需要一个对 search-manager
组成部分,以及 $ctrl
不在范围内。
我们如何获得对父体的引用?
要获得父类的引用,你需要做的是 require
亲家 search-context
声明。双关语前缀的意思是搜索父对象。单尾号从当前对象开始,可以用,但效率略低。问号的意思是找不到就不要吧,直接返回undefined。当组件可能并不总是被搜索管理器作为父对象时,这一点是必要的。
angular.module("app").component("searchContext", {
templateUrl: "/app/components/search-context.html",
controller: SearchContextController,
require: {
searchManagerCtrl: "?^^searchManager"
},
bindings: {
...
}
});
但如果你需要父类有对子类的引用呢?
在 SearchContextController
我们实施 $onInit
生命周期事件处理程序。
ctrl.$onInit = function () {
if (ctrl.searchManagerCtrl) {
ctrl.searchManagerCtrl.registerSearchContext(ctrl);
}
};
registerSearchContext
是一个在父控制器中定义的方法,用于此目的。其实现本质上是将每个注册的控件推送到我们在其作用域上定义的一个数组属性中,然后父控制器的方法可以枚举子控制器。
对于一个指令来说,这 require
技巧的表达方式略有不同。你必须声明属性 searchManagerCtrl
中的表达式,并直接将其作为 require 的值。
require: "?^^searchManager",
你还必须提供一个 link
函数的参数之一。的参数之一。link
功能是 controller
并提及 searchManager
将被传递到这个参数中,这时你可以将它分配给指令作用域的一个属性。在这个参数中,你可以将它分配给指令作用域的一个属性。$onInit
生命周期事件仍可在搜索管理器中注册,但指的是 $scope
而非 ctrl
.