在 Angular 1.5 组件中实现组件 require 属性

Posted

技术标签:

【中文标题】在 Angular 1.5 组件中实现组件 require 属性【英文标题】:Implementing component require property in Angular 1.5 components 【发布时间】:2017-01-22 09:31:29 【问题描述】:

我不喜欢将require: 属性作为角度组件的一部分来实现。请允许我用我的示例进行演示。

这是应该获取判断列表的组件/指令。没什么特别的,只是一个简单的工厂调用。

// judgements.component.js
function JudgementsController(GetJudgements) 
    var ctrl = this;

    ctrl.Get = function () 
        GetJudgements.get().$promise.then(
            function (data) 
                ctrl.Judgements = data.judgements;
            , function (error) 
                // show error message
            );
    

    ctrl.$onInit = function () 
        ctrl.Get();
    ;


angular
    .module('App')
    //.component('cJudgements', 
    //    controller: JudgementsController,
    //);
    .directive('cJudgements', function () 
        return 
            scope: true,
            controller: 'JudgementsController',
            //bindToController: true,
        ;
    );

我正在尝试实现组件要求属性,以使我可以从上述组件/指令访问ctrl.Judgements,如下所示:

// list.component.js
function ListController(GetList, GetJudgements) 
    var ctrl = this;
    ctrl.list = [];

    ctrl.Get = function () 
        GetList.get().$promise.then(
            function (data) 
                ctrl.list = data.list;
            , function (error) 
                // show error message
            );
    ;

    //ctrl.GetJudgements = function () 
    //    GetJudgements.get().$promise.then(
    //        function (data) 
    //            ctrl.Judgements = data.judgements;
    //        , function (error) 
    //            // show error message
    //        );
    //

    ctrl.$onInit = function () 
        ctrl.Get();
        //ctrl.GetJudgements();
    ;


angular
    .module('App')
    .component('cTheList', 
        bindings: 
            listid: '<',
        ,
        controller: ListController,
        controllerAs: 'ctrl',
        require: 
            jCtrl: 'cJudgements',
        ,
        template: `
            <c-list-item ng-repeat="item in ctrl.list"
                         item="item"
                         judgements="ctrl.Judgements"></c-list-item>
           <!--
           obviously the reference to judgements here needs to change
           or even better to be moved into require of cListItem component
           -->
        `,
    );

很好很简单,不涉及魔法。敏锐的读者可能注意到ListController 中的GetJudgement 服务调用。这就是我试图使用 require 属性从 TheList 组件中删除的内容。

原因?其实很简单。我想尽可能地阻止数据库受到判断请求的冲击。这是一个静态列表,实际上没有必要为每个应用实例多次请求它。

到目前为止,我只成功收到以下错误消息:

Error: $compile:ctreq
Missing Required Controller
Controller 'cJudgements', required by directive 'cTheList', can't be found!

谁能看到我做错了什么? PS:我使用的是 Angular 1.5 PSS:我不介意 cJudgement 的实现方式(指令或组件)。 PSSS:如果有人想知道我尝试过使用jCtrl: '^cJudgements'。 PSSSS:还有多个^s,以防万一。

编辑

@Kindzoku 发布了一个指向the article 的链接,我在发布问题之前已经阅读了该链接。我希望这也有助于理解 Angular 1.5+ 中的 $onInitrequire

Plunker

由于大众的需求,我做了一个plunker 的例子。

【问题讨论】:

以上错误的意思是,没有使用控制器cJudgements定义的父html元素,顺便说一句,你必须注入服务而不需要它 我不明白你的 $onInit 实现。应该是这样的: this.$onInit = function() this.method = this.requiredName.requiredMethod() @entre 该错误仅表示无法找到cJudgements。没有使用cJudgements 定义的父 html。如您所见,它只是一个服务调用的包装器。 我想是时候使用重型火炮了。准备 Plunker:D @Kindzoku 哈哈,等到我这样做的时候,我可能会找到解决办法:p 我会尝试在早上整理一个。 【参考方案1】:

您应该在this.$onInit = function() 中使用所需的组件

这是一篇好文章https://toddmotto.com/on-init-require-object-syntax-angular-component/

你的 $onInit 应该这样写:

ctrl.$onInit = function () 
    ctrl.jCtrl.Get();
;

【讨论】:

我真的不明白它对 OP 有什么帮助? 嘿,我实际上是在发帖之前阅读了那篇文章。抱歉,我发布的示例没有使用 $onInit,但我的真实代码使用了。我更新了示例。 是的,我知道。这不是问题所在。问题出在require: jCtrl: 'cJudgements', 不管怎样,明天早上我会放一个plunker给大家玩。【参考方案2】:

@iiminov 有正确的答案。没有定义父 HTML c-judgements

Working plunker.

【讨论】:

以上是关于在 Angular 1.5 组件中实现组件 require 属性的主要内容,如果未能解决你的问题,请参考以下文章

Angular 1.5 组件依赖注入

Angular 1.5 组件示例

Angular 1.5 组件路由器兄弟组件

Angular 1.5 组件:基于组件的应用程序架构

Angular 1.5 父子组件问题

在 Angular 1.5 组件中使用 $emit