1

我熟悉AngularJS中的controllerAs語法,當我需要對服務變量進行簡單綁定時,我遇到了一個問題。通常$scope.$watch$scope.$on會這樣做,但是這將涉及注入$scope,這似乎違背了控制器的目的。

目前我有什麼是點擊一個按鈕,並呼籲config.setAttribute(attr)後,控制器調用服務的setAttribute功能,但不getAttribute,所以config.attribute永遠不會改變。

有什麼我忽略了我如何接近這個?我需要注入$scope還是改變控制器的語法來改爲使用$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; 
    } 
}})(); 

控制器:

(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(); 
    } 
}})(); 
+1

注入'$ scope'並不違背控制器的目的。這很重要 - 當需要將'$ scope'作爲'$ watch'和'$ on'之類的服務注入時,而不是默認爲了發佈ViewModel屬性。 –

+0

http://www.fullstacktraining.com/articles/angularjs-using-watch-with-controlleras –

+0

感謝您的評論,他們絕對清除了我的困惑。 – bliptych

回答

0

這裏是我的控制器看起來李柯注射$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(); 
    }); 

}})(); 

我也有噶測試的情況下,任何人有興趣:

(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); 
      }); 
     }); 
    }); 
})(); 

感謝您的幫助。我歡迎任何其他人可能擁有的更好的答案。

+0

我知道這個問題有點老。所以就像一個提示:如果你想縮小你的代碼,不要使用隱式注入。請參閱https://docs.angularjs.org/guide/di#implicit-annotation – Philipp