Javascript 为什么我的$watch在我的指令测试-Angularjs中不工作

Javascript 为什么我的$watch在我的指令测试-Angularjs中不工作,javascript,angularjs,Javascript,Angularjs,我有一个指令,在该指令中我传入一个attrs,然后它在指令中被监视。更改attrs后,将发生动画。触发$watch时,Myattrs始终未定义 App.directive('resize', function($animate) { return function(scope, element, attrs) { scope.$watch(attrs.resize, function(newVal) { if(newVal) { $animate.addC

我有一个指令,在该指令中我传入一个
attrs
,然后它在指令中被监视。更改
attrs
后,将发生动画。触发
$watch
时,My
attrs
始终未定义

App.directive('resize', function($animate) {
  return function(scope, element, attrs) {
    scope.$watch(attrs.resize, function(newVal) {
      if(newVal) {
        $animate.addClass(element, 'span8');
      }
    });
  };
});
这是我的测试:

describe('resize', function() {
  var element, scope;
  beforeEach(inject(function($compile, $rootScope) {
    var directive = angular.element('<div class="span12" resize="isHidden"></div>');
    element = $compile(directive)($rootScope);
    $rootScope.$digest();
    scope = $rootScope;
  }));

  it('should change to a span8 after resize', function() {
    expect($(element).hasClass('span12')).toBeTruthy();
    expect($(element).hasClass('span8')).toBeFalsy();
    element.attr('resize', 'true');
    element.scope().$apply();
    expect($(element).hasClass('span8')).toBeTruthy();
  });
});
description('resize',function()){
var元素、范围;
beforeach(注入函数($compile,$rootScope){
var指令=角度元素(“”);
元素=$compile(指令)($rootScope);
$rootScope.$digest();
scope=$rootScope;
}));
它('调整大小后应更改为span8',函数(){
expect($(element.hasClass('span12')).toBeTruthy();
expect($(element.hasClass('span8')).toBeFalsy();
attr('resize','true');
element.scope().$apply();
expect($(element.hasClass('span8')).toBeTruthy();
});
});

attrs
更改时,我的观察者
newValue
未定义,因此不会发生任何事情。我需要做些什么才能让它工作?这是一个

您没有看到属性的值。调整大小;您看到的是由
attrs.resize
指向的值,而在测试用例中,一个名为
ishiden
的范围成员。这不存在,因此
未定义

对于您正在尝试做的事情,以下几点会起作用:

App.directive('resize', function($animate) {
    return function(scope, element, attrs) {
        scope.$watch(
            // NOTE THE DIFFERENCE HERE
            function() {
                return element.attr("resize");
// EDIT: Changed in favor of line above...
//              return attrs.resize;
            },
            function(newVal) {
                if(newVal) {
                    $animate.addClass(element, 'span8');
                }
            }
        );
    };
});


编辑:对于非插值的值,
attrs
对象似乎不会从DOM更新中得到更新。因此,您必须查看
element.attr(“resize”)
。我担心这是无效的,虽然。。。请参阅forked plunk:

以下是我如何使此测试正常工作的。我将变量作为
attr
传递给指令。变量名为
ishiden
。下面是我的测试,更新后的代码正在运行

describe('resize', function() {
  var element, scope;
  beforeEach(inject(function($compile, $rootScope) {
    var directive = angular.element('<div class="span12" resize="isHidden"></div>');
    element = $compile(directive)($rootScope);
    $rootScope.$digest();
    scope = $rootScope;
  }));

  it('should change to a span8 after resize', function() {
    expect($(element).hasClass('span12')).toBeTruthy();
    expect($(element).hasClass('span8')).toBeFalsy();
    element.scope().isHidden = true;
    scope.$apply();
    expect($(element).hasClass('span8')).toBeTruthy();
  });
});
description('resize',function()){
var元素、范围;
beforeach(注入函数($compile,$rootScope){
var指令=角度元素(“”);
元素=$compile(指令)($rootScope);
$rootScope.$digest();
scope=$rootScope;
}));
它('调整大小后应更改为span8',函数(){
expect($(element.hasClass('span12')).toBeTruthy();
expect($(element.hasClass('span8')).toBeFalsy();
element.scope().ishiden=true;
作用域:$apply();
expect($(element.hasClass('span8')).toBeTruthy();
});
});
我可以通过附加到
元素的作用域访问变量
ishiden
。更改变量后,我必须运行
$digest
进行更新,然后一切都是金色的


我觉得我应该在这里使用
$observe
,正如
软件包所指出的那样。我会看看这一点,并添加一个评论,当我得到它的工作

正如Nikos指出的,问题在于您没有注意attrs.resize的值,因此您可以尝试这样做:

describe('resize', function() {
  var element, scope;
  beforeEach(inject(function($compile, $rootScope) {
    var directive = angular.element('<div class="span12" resize="isHidden"></div>');
    element = $compile(directive)($rootScope);
    $rootScope.$digest();
    scope = $rootScope;
  }));

  it('should change to a span8 after resize', function() {
    expect($(element).hasClass('span12')).toBeTruthy();
    expect($(element).hasClass('span8')).toBeFalsy();
    element.scope().isHidden = true;
    scope.$apply();
    expect($(element).hasClass('span8')).toBeTruthy();
  });
});
创建用于保存数据的变量,并创建以下$watch函数:

var dataGetter;

scope.$watch(function () {
    return attrs.resize;
}, function (newVal) {
    dataGetter = $parse(newVal);
});

scope.$watch(function () {
    return dataGetter && dataGetter(scope);
}, function (newVal) {
    // Do stuff here         
});

这里应该发生的是Angular的
$parse
函数应该计算
attrs.resize
并返回如下函数。然后你通过这个范围做一些事情。只要
attrs.resize
只是一个布尔值,那么我希望第二个watch表达式中的newVal应该是一个布尔值。

您能对此进行修改吗?而不是
element.attr('resize','true')
,尝试将该行更改为
element.scope()。resize=true。行吗?不行,不行。我添加了一个plunker。在本例中,我将使用
attrs.$observe
。我复制并粘贴了您的代码以用于我的指令,但它仍然不起作用。我是否需要更改测试中的某些内容?@package我的异议是,
$observe
应该监视插值。对于非插值的值,
attrs
对象似乎不会从DOM更新中得到更新。正在更新答案。。。