GVKun编程网logo

使用AngularJS HotTowel中的vm“ ControllerAs”语法从单元测试文件访问$ scope(angular单元测试怎么做)

8

以上就是给各位分享使用AngularJSHotTowel中的vm“ControllerAs”语法从单元测试文件访问$scope,其中也会对angular单元测试怎么做进行解释,同时本文还将给你拓展an

以上就是给各位分享使用AngularJS HotTowel中的vm“ ControllerAs”语法从单元测试文件访问$ scope,其中也会对angular单元测试怎么做进行解释,同时本文还将给你拓展angular controller as syntax vs scope、angular – 如何从单元测试中访问注入的ngControl?、AngularJS Controller和rootScope的多种用法、angularjs – Angular Controller As Syntax-no method’$watchCollection’等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

使用AngularJS HotTowel中的vm“ ControllerAs”语法从单元测试文件访问$ scope(angular单元测试怎么做)

使用AngularJS HotTowel中的vm“ ControllerAs”语法从单元测试文件访问$ scope(angular单元测试怎么做)

例如,请参见此处:http : //www.johnpapa.net/angularjss-controller-as-and-the-vm-
variable/

就像标题所暗示的那样,我将按照本教程 [http://tech.pro/tutorial/1473/getting-started-with-
angularjs-unit-testing]进行单元测试,事实证明一切都很好。 我似乎无法将vm变量 作为$ scope 来访问。

dashboard.js

var controllerId = ''dashboard'';angular.module(''app'')    .controller(controllerId, [''common'', ''datacontext'', dashboard]);function dashboard(common, datacontext) {    var getLogFn = common.logger.getLogFn;    var log = getLogFn(controllerId);    var vm = this;          vm.title = ''Dashboard'';

仪表板.Spec.js

describe("app module", function() {    beforeEach(module("app"));    describe("dashboard", function() {        var scope,            controller;        beforeEach(inject(function($rootScope, $controller) {            scope = $rootScope.$new();            controller = $controller;        }));        it("should assign Dashboard as title", function() {            controller("dashboard", {                $scope: scope            });            expect(scope.title).toBe("Dashboard");        });    });});

我尝试过的方法:当我直接在控制器依赖项中命名“ $ scope”并将其设置为“ title”属性时,它可以工作(测试通过)。但是,我想保持原样。

我还尝试过直接在依赖项中传递$ scope并将控制器参数命名为“ vm” …

Karmas测试失败消息为: 预期未定义为“仪表板”

感谢任何帮助!

答案1

小编典典

嗯,现在很明显…我可以通过引用测试中创建的控制器来访问vm变量:

 it("should assign Dashboard as title", function () {       var vm = controller("dashboard", { $scope: scope });       expect(vm.title).toBe("Dashboard");    });

angular controller as syntax vs scope

angular controller as syntax vs scope

今天要和大家分享的是angular从1.2版本开始带来了新语法Controller as。再次之前我们对于angular在view上的绑定都必须使用直接的scope对象,对于controller来说我们也得必须注入$scope这个service。如下:

angular.module("app",[])
  .controller("demoController",["$scope",function($scope){
    $scope.title = "angualr";
  }])

 <div ng-app="app" ng-controller="demoController">
      hello : {% raw %}{{title}}{% endraw %} !
</div>

有些人觉得即使这样我们的controller还是不够POJO,以及对于coffescript爱好者不足够友好,所以在angular在1.2给我带来了一个新的语法糖这就是本文将要说的controller as的语法糖,修改上面的demo将会变成:

angular.module("app",[])
  .controller("demoController",[function(){
    this.title = "angualr";
  }])

  <div ng-app="app" ng-controller="demoController as demo">
        hello : {% raw %}{{demo.title}}{% endraw %} !
  </div> 

这里我们可以看见现在controller不再有$scope的注入了,感觉controller就是一个很简单的平面的JavaScript对象了,不存在任何的差别了。再则就是view上多增加了个demoController as demo,给controller起了一个别名,在此后的view模板中靠这个别名来访问数据对象。

或许看到这里你会问为什么需要如此啊,不就是个语法糖而已,先别着急,我们会在后边分析$scope和他的差别。在此之前我们先来看看angular源码的实现这样才会有助于我们的分析:

下面是一段来自angular的code:在1499行开始(行数只能保证在写作的时候有效)

if (directive.controllerAs) {
          locals.$scope[directive.controllerAs] = controllerInstance;
   }

如果你希望看更完全的code请猛击这里https://github.com/angular/angular.js/blob/c7a1d1ab0b663edffc1ac7b54deea847e372468d/src/ng/compile.js.

从上面的代码我们能看见的是:angular只是把controller这个对象实例以其as的别名在scope上创建了一个新的对象属性。靠,就这么一行代码搞定!

先别急,既然是语法糖,那么它肯定有他出现的原因,让我们来和直接用$scope对比下:

在此文之前我在angularjs的群中和大家讨论了下我的看法,得到大家不错的反馈,所以有了本文,记录和分享下来。

我规定对于controller as的写法如下:

angular.module("app",[])
 .controller("demoController",[function(){
        var vm = this;

        vm.title = "angualr";

        return vm;
 }])

其优势为:

  1. 定义vm这样会让我们更好的避免JavaScript的this的坑。
  2. 如果某个版本的angular不再支持controller as,可以轻易的注入$scope,修改为 var vm = $scope;
  3. 因为不再注入$scope了,controller更加的POJO,就是一个很普通的JavaScript对象。
  4. 也因为没有了$scope,而controller实例将会成为scope上的一个属性,所以在controller中我们再也不能使用$watch,$emit,$on之类的特殊方法,因为这些东西往往不该出现在controller中的,给大家一个警告,更好的控制。但是一旦如果没办法必须用的话,可以在征得项目组一致同意,将此controller退回$scope.
  5. 因为controller实例将会只是$scope的一个属性,所以view模板上的所有字段都会在一个引用的属性上,这可以避开JavaScript原型链继承对于值类型的坑。参加https://github.com/angular/angular.js/wiki/Understanding-Scopes.
  6. controller as 对于 coffescript,liveScript更友好。
    7.模板上定义的每个字段方法都会在scope寄存在controller as别名上的引用上,所以在controller继承中,不会在出现命名冲突的问题。

注释:对于route,也有个controllerAs的属性可以设置,下面代码来之angular doc文档:

angular.module(''ngViewExample'', [''ngRoute'', ''ngAnimate''],
      function($routeProvider, $locationProvider) {
    $routeProvider.when(''/Book/:bookId'', {
      templateUrl: ''book.html'',
      controller: BookCntl,
      controllerAs: ''book''
    });
    $routeProvider.when(''/Book/:bookId/ch/:chapterId'', {
      templateUrl: ''chapter.html'',
      controller: ChapterCntl,
      controllerAs: ''chapter''
    });

    // configure html5 to get links working on jsfiddle
            $locationProvider.html5Mode(true);
        });

angular – 如何从单元测试中访问注入的ngControl?

angular – 如何从单元测试中访问注入的ngControl?

如何从单元测试中访问注入的ngControl?
如何解决错误?

在组件中

constructor(
    @Self() @Optional() public ngControl: NgControl
  ) { }

ngOnInit(): void {
    this.ngControl.valueChanges

在单元测试中

beforeEach(() => {
      fixture = Testbed.createComponent(component);
      fixture.detectChanges();

执行测试时得到错误

TypeError:无法读取null的属性’valueChanges’

适用于:
beforeEach(() => {
     fixture = Testbed.createComponent(сomponent);
     (fixture.componentInstance as any).ngControl = new FormControl();

AngularJS Controller和rootScope的多种用法

AngularJS Controller和rootScope的多种用法

我想对2个单独的HTML元素使用控制器,并使用$ rootScope在编辑一个列表时使2个列表保持同步:

HTML

<ulng-controller="Menu">
    <li ng-repeat="item in menu">
        <a href="{{item.href}}">{{item.title}}</a>
    </li>
</ul>

<div ng-controller="Menu">
    <input type="text" id="newItem" value="" />
    <input type="submit" ng-click="addItem()" />
    <ulng-controller="Menu">
        <li ng-repeat="item in menu">
            <a href="{{item.href}}">{{item.title}}</a>
        </li>
    </ul>    
</div>

JS

angular.module('menuApp',['menuServices']).
    run(function($rootScope){
        $rootScope.menu = [];
    });

angular.module('menuServices',['ngResource']).
    factory('MenuData',function ($resource) {
        return $resource(
            '/tool/menu.cfc',{
                returnFormat: 'json'
            },{
                getMenu: {
                    method: 'GET',params: {method: 'getMenu'}
                },addItem: {
                    method: 'GET',params: {method: 'addItem'}
                }
            }
        );
    });

function Menu($scope,MenuData) {

    // attempt to add new item
    $scope.addNewItem = function(){
        var thisItem = $('#newItem').val();

        MenuData.addItem({item: thisItem},function(data){
            $scope.updateMenu();
        });
    }

    $scope.updateMenu = function() {
        MenuData.getMenu({},function(data){
            $scope.menu = data.MENU;
        });         
    }

    // get menu data
    $scope.updateMenu();
}

页面加载时,UL和均DIV显示数据库中正确的内容,但是当我使用该addNewItem()方法时,仅DIV更新。

有没有更好的方法来组织我的逻辑,或者我可以做一些事情,以确保$scope.menuUL获取的同时更新?

这是类似的示例:http :
//plnkr.co/edit/2a55gq

angularjs – Angular Controller As Syntax-no method’$watchCollection’

angularjs – Angular Controller As Syntax-no method’$watchCollection’

我试图在Angular中将Controller作为语法.在这一点上,我在我的routerProvider中有它…不确定它对我遇到的问题是否重要,但在这里它仍然是:

angular.module('ucp.kick',[
  'ngRoute'
])
.config ($routeProvider,APP_BASE_URL) ->
  $routeProvider
  .when APP_BASE_URL + 'kicks',name: 'Kicks'
    templateUrl: 'kick/partials/kick.html'
    controller: 'kick as KickController'

这是我的控制器的浓缩版本:

this.$watchCollection('filtered.devices',function(devices) {
    return this.filteredDevices = devices;
  });

但我得到:

TypeError: Object [object Object] has no method '$watchCollection'

我意识到当使用控制器作为语法时,您不希望注入范围.那么,我如何访问$watchCollection函数?

解决方法

你仍然需要注入$scope才能使用$watch和$watchCollection.现在,你会认为你可以这样做:

$scope.$watchCollection('filtered.devices',function (newVal,oldVal) {});

要么

$scope.$watchCollection('this.filtered.devices',oldVal) {});

但那不行.所以你需要做:

var that = this;
$scope.$watchCollection(function () {
    return that.filtered.devices;
},oldVal) {

});

要么:

$scope.$watchCollection(angular.bind(this,function () {
    return this.filtered.devices;
}),oldVal) {

});

要么:

$scope.$watchCollection("KickController.filtered.devices",function(newVal,oldVal) { });

关于使用AngularJS HotTowel中的vm“ ControllerAs”语法从单元测试文件访问$ scopeangular单元测试怎么做的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于angular controller as syntax vs scope、angular – 如何从单元测试中访问注入的ngControl?、AngularJS Controller和rootScope的多种用法、angularjs – Angular Controller As Syntax-no method’$watchCollection’等相关内容,可以在本站寻找。

本文标签: