2013-07-31 94 views
12

我有一個指令,使用隔離範圍將數據傳遞到隨時間變化的指令。它會監視該值的變化並對每次更改進行一些計算。當我嘗試單元測試指令,我不能拿到手錶觸發(修剪簡潔,但基本概念如下圖所示):單元測試AngularJS指令,觀察與隔離範圍的屬性

指令:

angular.module('directives.file', []) 
.directive('file', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     data: '=', 
     filename: '@', 
    }, 
    link: function(scope, element, attrs) { 
     console.log('in link'); 
     var convertToCSV = function(newItem) { ... }; 

     scope.$watch('data', function(newItem) { 
     console.log('in watch'); 
     var csv_obj = convertToCSV(newItem); 
     var blob = new Blob([csv_obj], {type:'text/plain'}); 
     var link = window.webkitURL.createObjectURL(blob); 
     element.html('<a href=' + link + ' download=' + attrs.filename +'>Export to CSV</a>'); 
     }, true); 
    } 
    }; 
}); 

測試:

describe('Unit: File export', function() { 
    var scope; 

    beforeEach(module('directives.file')); 
    beforeEach(inject(function ($rootScope, $compile) { 
    scope = $rootScope.$new(); 
    }; 

    it('should create a CSV', function() { 
    scope.input = someData; 
    var e = $compile('<file data="input" filename="filename.csv"></file>')(scope); 
    //I've also tried below but that does not help 
    scope.$apply(function() { scope.input = {}; }); 
    }); 

我能做些什麼來觸發手錶,所以我的「手錶」調試語句被觸發?當我編譯時,我的「鏈接」被觸發。

回答

15

對於$watch得到觸發,必須在它被定義的範圍或其父發生消化週期。由於您的指令創建了一個隔離範圍,因此它不會從父範圍繼承,因此只有在適當範圍內調用$apply之後,才能處理其觀察者。

您可以通過調用$compile服務返回的元素上scope()訪問指令範圍:

scope.input = someData; 
var e = $compile('<file data="input" filename="filename.csv"></file>')(scope); 
e.isolateScope().$apply(); 

jsFiddler例舉了。