AngularJS 1.6独立组件通信实现问题:require关键字报错求助
解决AngularJS 1.6组件通信中require报错的问题
你遇到的$compile:ctreq错误,核心原因是**require的查找规则没搞对**——AngularJS里组件的require只能在当前组件的父级元素或者自身元素上寻找指定的控制器,如果你两个组件是平级关系,或者没正确指定查找范围,就会找不到目标控制器。
下面分两种常见场景给你解决方案:
场景1:两个组件是父子嵌套关系
如果ctwo是嵌套在cone内部的子组件,那只需要在ctwo的require配置里加上^符号,明确告诉AngularJS去父级查找cone的控制器。
修改后的完整代码:
angular.module("app", []) .component('cone', { template: ` <p>Component one</p> <ctwo></ctwo> <!-- 把ctwo嵌套在cone的模板里 --> `, controller: function() { console.log("component one loaded") this.fone = function() { console.log("component one function one") } } }) .component('ctwo', { template: '<p>Component two</p>', // 用^cone表示向上查找父级的cone组件控制器,别名coneCtrl方便调用 require: { coneCtrl: '^cone' }, controller: function() { this.$onInit = function() { // 在初始化钩子中就能拿到父组件的控制器,调用它的方法 this.coneCtrl.fone(); } console.log("component two loaded") } });
然后在HTML里只需要渲染父组件即可:
<cone></cone>
场景2:两个组件是平级关系
如果cone和ctwo是平级的(比如都在同一个父容器下),require就派不上用场了,这时候需要用共享服务来做中间通信。
步骤1:创建共享服务
这个服务用来存放共享的方法或者实现事件订阅/发布机制:
angular.module("app", []) .service('ComponentCommService', function() { // 事件订阅 this.listeners = {}; this.on = function(eventName, callback) { if (!this.listeners[eventName]) { this.listeners[eventName] = []; } this.listeners[eventName].push(callback); }; // 事件发布 this.emit = function(eventName, data) { if (this.listeners[eventName]) { this.listeners[eventName].forEach(callback => callback(data)); } }; })
步骤2:在两个组件中注入并使用服务
// cone组件:订阅事件,暴露自己的方法 .component('cone', { template: '<p>Component one</p>', controller: function(ComponentCommService) { console.log("component one loaded") this.fone = function() { console.log("component one function one") } // 订阅来自ctwo的调用事件 ComponentCommService.on('callConeFone', () => { this.fone(); }); } }) // ctwo组件:发布事件,触发cone的方法 .component('ctwo', { template: '<p>Component two</p>', controller: function(ComponentCommService) { console.log("component two loaded") // 发布事件,调用cone的方法 ComponentCommService.emit('callConeFone'); } });
平级组件的HTML写法:
<div> <cone></cone> <ctwo></ctwo> </div>
常见错误点提醒
- 忘记加
^符号:如果require只写'cone',AngularJS会在当前ctwo元素上查找cone控制器,自然找不到,必须加^指定父级查找。 - 组件层级错误:平级组件不要硬用
require,这不符合AngularJS的设计逻辑,服务是更合适的方案。 - 名称拼写错误:确保
require里的组件名和定义的组件名完全一致(比如组件定义是cone,就不能写成conOne)。
内容的提问来源于stack exchange,提问作者Ebin Manuval
相关产品推荐
相关产品推荐

