angularjs绑定到具有隔离范围的控制器

时间:2017-05-11 09:39:18

标签: angularjs

我有一个非常简单的指令,我想使用 bindToController 选项。所以,我创建了这样的指令:

(function () {
    'use strict';

    angular.module('sapphire.directives').directive('list', list);

    function list() {
        return {
            restrict: 'A',
            template: '<div class="row flex-column" ng-class="{ \'spinner-dark\': controller.loading }" ng-include="controller.templateUrl" ng-if="controller.loading || controller.models.length"></div>',
            controller: 'ListDirectiveController',
            controllerAs: 'controller',
            scope: true,
            bindToController: {
                method: '&list',
                templateName: '@'
            }
        };
    };
})();

然后我像这样创建了我的控制器:

(function () {
    'use strict';

    angular.module('sapphire.directives').controller('ListDirectiveController', listDirectiveController);

    listDirectiveController.$inject = ['ListDirectiveService', 'Selections'];

    function listDirectiveController(broadcast, selections) {
        var self = this;

        console.log(self);

        // Bindings
        self.limit = 0;
        self.total = 0;
        self.loading = true;
        self.templateUrl = 'app/directives/lists/list/' + (self.templateName || 'list-default') + '.html';
        self.isSelected = selections.isSelected;
        self.select = selections.select;

        // Method binding
        self.list = list;

        init();

        //////////////////////////////////////////////////

        function init() {
            list();
        };

        // Our list method
        function list() {

            // Set our initial limit
            self.limit += 10;
            self.loading = true;

            // Get our items
            return self.method({ limit: self.limit }).then(function (response) {
                self.loading = false;
                self.models = response;
                self.total = response.length;
            });
        };

        ///////// ------ Removed for brevity ------ /////////
    };
})();

当我使用此指令时,我收到一条错误说明:

  

self.method不是函数

这就是为什么我是console.logging控制器以查看绑定到它的内容。当然,缺少方法 templateName 。 我尝试了几种方法来实现这一点:

scope: {
    method: '&list',
    templateName: '@'
},
bindToController: true

scope: {},
bindToController: {
    method: '&list',
    templateName: '@'
}

但似乎没有任何效果。我无法将我的孤立范围绑定到我的控制器.... 有谁知道我做错了什么?

PS:我使用的是角1.6.4

要使用指令我这样做:

<div class="invisible-container" list="controller.listUsers(limit)" template-name="users"></div>

1 个答案:

答案 0 :(得分:0)

好的,所以我想出来了。范围是有约束力的,但不能立即获得。我必须创建一个 init 方法并从指令中调用它。只有这样一切都受到约束。 我是这样做的:

(function () {
    'use strict';

    angular.module('sapphire.directives').directive('list', list);

    function list() {
        return {
            restrict: 'A',
            template: '<div class="row flex-column" ng-class="{ \'spinner-dark\': controller.loading }" ng-include="controller.templateUrl" ng-if="controller.loading || controller.models.length"></div>',
            controller: 'ListDirectiveController',
            controllerAs: 'controller',
            scope: {
                method: '&list',
                templateName: '@'
            },
            bindToController: true,
            link: function (scope, element, attrs, controller) {
                controller.init();
            }
        };
    };
})();

,控制器现在看起来像这样:

(function () {
    'use strict';

    angular.module('sapphire.directives').controller('ListDirectiveController', listDirectiveController);

    listDirectiveController.$inject = ['ListDirectiveService', 'Selections'];

    function listDirectiveController(broadcast, selections) {
        var self = this;

        // Bindings
        self.limit = 0;
        self.total = 0;
        self.loading = true;
        self.isSelected = selections.isSelected;
        self.select = selections.select;

        // Method binding
        self.init = init;

        ////////////////////////////////////////////////////

        function init() {
            list();
            getTemplate();
            bindEvents();
        };

        function bindEvents() {
            broadcast.onPrepend(onPrepend);
            broadcast.onRefresh(onRefresh);
        };

        function getTemplate() {
            self.templateUrl = 'app/directives/lists/list/' + (self.templateName || 'list-default') + '.html';
        };

        function list() {

            // Set our initial limit
            self.limit += 10;
            self.loading = true;

            // Get our items
            return self.method({ limit: self.limit }).then(function (response) {
                self.loading = false;
                self.models = response;
                self.total = response.length;
            });
        };

        function onPrepend(event, args) {
            if (args && args.target && args.target === self.templateName) {
                self.models.unshift(args.model);
            }
        };

        function onRefresh(event, args) {
            if (args && args.target && args.target === self.templateName) {
                self.limit -= 10;
                self.models = [];
                list();
            }
        };
    };
})();