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不是一个函数

这就是为什么我要控制台记录控制器以查看绑定到它的内容。当然,方法模板名称丢失了。我已经尝试了几种方法来使其工作:

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>

好的,所以我想通了。范围是绑定的,但不能立即使用。我必须创建一个 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();
            }
        };
    };
})();

最新更新