javascript - 使用 ControllerAs 语法与服务变量绑定(bind)而不使用 $scope?

标签 javascript angularjs angularjs-scope watch angularjs-controlleras

我正在熟悉 AngularJS 中的controllerAs 语法,当我需要对服务变量进行简单绑定(bind)时,我遇到了问题。通常使用 $scope.$watch$scope.$on 即可,但这会涉及注入(inject) $scope,这似乎会击败 Controller As的目的。

目前我所拥有的是,单击其中一个按钮并调用 config.setAttribute(attr) 后, Controller 调用服务的 setAttribute 函数,而不是 getAttribute,因此 config.attribute 永远不会改变。

我在处理这个问题时是否忽略了一些事情?我需要注入(inject) $scope 或更改 Controller 语法以使用 $scope 吗?

查看:

<div data-ng-controller="ConfigCtrl as config">
    <h3>Customize</h3>
    <pre>Current attribute: {{config.attribute}}</pre>

    <label>Attributes</label>
    <div data-ng-repeat="attr in config.attributes">
        <button ng-click="config.setAttribute(attr)">{{attr.name}}</button>
    </div>
</div>

服务:

(function() {
'use strict';

angular.module('app')
.factory('Customization', Customization);

function Customization() {
    var service = {
        attribute: null,
        getAttributes: getAttributes,
        setAttribute: setAttribute,
        getAttribute: getAttribute
    }
    return service;
    /////
    function getAttributes() {
        return [
            {name: 'Attr1', value: '1'},
            {name: 'Attr2', value: '2'} // etc.
        ];
    }

    function setAttribute(attr) {
        service.attribute = attr;
    }

    function getAttribute() {
        return service.attribute;
    }
}})();

Controller :

(function(){
'use strict';

angular.module('app')
.controller('ConfigCtrl', ConfigCtrl);

function ConfigCtrl(Customization){
    var vm = this;

    vm.attribute = Customization.getAttribute(); // bind
    vm.attributes = [];

    // Functions
    vm.setAttribute = Customization.setAttribute;

    init();
    /////
    function init(){
        // Get attributes array
        vm.attributes = Customization.getAttributes();
    }
}})();

最佳答案

这是我的 Controller 在注入(inject) $scope 并添加 attribute 监视后的样子:

(function(){
'use strict';

angular.module('app')
.controller('ConfigCtrl', ConfigCtrl);

function ConfigCtrl($scope, Customization){
    var vm = this;

    vm.attribute;
    vm.attributes = [];

    // Functions
    vm.setAttribute = Customization.setAttribute;

    init();
    /////
    function init(){
        // Get attributes array
        vm.attributes = Customization.getAttributes();
    }

    $scope.$watch(function() {
        return Customization.getAttribute()
    }, function() {
        vm.attribute = Customization.getAttribute();
    });

}})();

我还有 Karma 测试,以防有人感兴趣:

(function() {
    'use strict';

    describe('ConfigCtrl', function () {

        var ConfigCtrl, scope;

        beforeEach(module('app'));

        beforeEach(inject(function($rootScope, $controller) {
            scope = $rootScope.$new();
            ConfigCtrl = $controller('ConfigCtrl',
                {$scope: scope}
            );
        }));

        describe('#setAttribute', function(){
            it('sets the current attribute', function(){
                var selected = {
                    name:'Attr1',
                    value:'1'
                };
                ConfigCtrl.setAttribute(selected);
                scope.$apply();
                expect(ConfigCtrl.attribute).to.eql(selected);
            });
        });
    });
})();

感谢您的帮助。欢迎其他人提出更好的答案。

关于javascript - 使用 ControllerAs 语法与服务变量绑定(bind)而不使用 $scope?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31899109/

相关文章:

javascript - 将 Jquery 对象作为键添加到另一个对象

javascript - 项目中不存在目标 "/t:native_metrics"

javascript - AngularJS $scope.variable 未定义

javascript - Highcharts numberFormat 返回负零

javascript - 为什么我在 View 中看不到这个变量?

angularjs - 为什么 Angular.js 的 Promise 比 JavaScript 中的回调更好

javascript - 替换 Cloudinary 上的图像

javascript - 按下右箭头时避免突出显示下一个字母javascript

javascript - 在 Angular 中重用部分和 Controller

angularjs - Controller 中 this 和范围的区别