2014-10-30 11 views
15

मैं निम्नलिखित निर्देश है:

!(function (window, angular) { 
    'use strict'; 

    /** 
    * @ngdoc directive 
    * @name app.directive:social 
    * @description 
    * # social 
    */ 
    angular.module('app') 
     .directive('social', function(social_network_conf) { 
      return { 
       restrict: 'A', 
       scope: { 
        social: "@" 
       }, 
       require: 'ngModel', 
       controller: function($scope, $element){ 
        //for tests only 
        $scope.render = function(){ 
         //how to I get the ngModel here 
         ngModel.$render(); 
        }; 

        $scope.setViewValue = function(val){ 
         ngModel.$setViewValue(val); 
        }; 
       }, 
       link: function(scope, element, attr, ngModel) { 

        ngModel.$formatters.push(function(value) {// from model to view 
         value = value.trim(); 
         if(value){ 
          if (value.indexOf(social_network_conf.matcher) === 0){ 
           var split_link = value.split(social_network_conf.divider); 
           return split_link[split_link.length-1]; 
          } 
          else{ 
           return value; 
          } 
         } 
        }); 

        ngModel.$parsers.push(function(value) { // from view to model 
         value = value.trim(); 
         if(value){ 
          if (value.indexOf(social_network_conf.matcher) === 0){ 
           return value; 
          } 
          else{ 
           return social_network_conf.prefix + scope.social + 
             social_network_conf.suffix + value; 
          } 
         } 
        }); 
       } 
      }; 
     }); 
}(window, window.angular)); 

परीक्षण निम्नलिखित के रूप में चला जाता है:

'use strict'; 

describe('Directive: social', function() { 

    // load the directive's module 
    beforeEach(module('app')); 

    var element, 
    social_network_conf, 
    linker, 
    scope, 
    $httpBackend; 

    beforeEach(inject(function ($rootScope, _$httpBackend_, _social_network_conf_) { 
    scope = $rootScope.$new(); 
     social_network_conf = _social_network_conf_; 
     //Must be an object to make use of prototypical inheritence for out-side-of-isolate-scope access 
     scope.models = {}; 

     $httpBackend = _$httpBackend_; 
     $httpBackend.whenGET(/views\/social.html/).respond('<div></div>'); 
     $httpBackend.whenGET(/views\/navigation.html/).respond('<div></div>'); 

    })); 

    it('It should convert ngModel into full HTTP address notation', inject(function ($compile) { 
    element = angular.element('<input social="test_network" ng-model="models.test_network"></social>'); 
    linker = $compile(element); 
    element = linker(scope); 
    scope.$apply(function(){ 
     element.val('test'); 
    }); 
    scope.$digest(); 
    expect(scope.models.test_network).toBe(social_network_conf.prefix + 'test' + 
      social_network_conf.suffix); 
// expect(element.text()).toBe('this is the social directive'); 
    })); 
}); 

समस्या यह है कि उन पंक्तियों:

scope.$apply(function(){ 
    element.val('test'); 
}); 

वास्तव में परिभाषित $ पार्सर का आह्वान न करें।

ngModel.$render या ngModel.$setViewValue पर कॉल करने के लिए एक एपीआई के साथ निर्देश के लिए नियंत्रक बनाने के बावजूद, लेकिन मेरे पास निर्देशक नियंत्रक पर nugModel को बदसूरत हैक के बिना पहुंचने का कोई तरीका नहीं है।

उत्तर

19

2 संभव समाधान:

पहले एक फार्म के अंदर तत्व रैप करने के लिए, और इनपुट क्षेत्र और फार्म एक name विशेषता आवंटित करने के लिए, और फिर निम्नलिखित के रूप में इनपुट क्षेत्र का उपयोग है:

scope.form_name.input_name.$setViewValue('value') 

कार्य कोड:

'use strict'; 

describe('Directive: social', function() { 

    // load the directive's module 
    beforeEach(module('app')); 

    var element, 
    social_network_conf, 
    linker, 
    scope, 
    $compile, 
    $body, 
    html, 
    $httpBackend; 

    beforeEach(inject(function ($rootScope, _$compile_, _$httpBackend_, _social_network_conf_) { 
    scope = $rootScope.$new(); 
     social_network_conf = _social_network_conf_; 
     //Must be an object to make use of prototypical inheritence for out-side-of-isolate-scope access 
     scope.models = {}; 
     $compile = _$compile_; 
     $httpBackend = _$httpBackend_; 
     $body = $('body'); 
     $httpBackend.whenGET(/views\/social.html/).respond('<div></div>'); 
     $httpBackend.whenGET(/views\/navigation.html/).respond('<div></div>'); 
     $body.empty(); 
     html = '<form name="testForm">' + 
       '<input social="test_network" name="test" ng-model="models.test_network">' + 
      '</form>'; 

    })); 

    it('It should convert ngModel into full HTTP address notation', function() { 

    element = angular.element(html); 
    linker = $compile(element); 
    element = linker(scope); 

    var viewValue = 'test', 
     input = element.find('input'); 

    scope.models.test_network = viewValue; 
    scope.$digest(); 

    scope.testForm.test.$setViewValue(viewValue); 

    scope.$digest(); 
    expect(scope.models.test_network).toBe(social_network_conf.prefix + input.isolateScope().social + 
      social_network_conf.suffix + viewValue); 

    }); 

वैकल्पिक रूप से, दूसरा एक तत्व पर एक इनपुट घटना प्रेषण करने के लिए प्रदान करता है - कोणीय 1.3 के साथ मेरे लिए काम नहीं किया। यह This YouTube video में प्रदर्शित किया गया है। आलसी के लिए

element.val('test'); 
element.trigger('input'); 
+1

मैं काम करने के लिए .val() .trigger() प्राप्त करने में सक्षम था। बहुत बहुत धन्यवाद – welbornio

+1

.val ("जो भी")। ट्रिगर ("इनपुट") भी मेरे लिए काम करता है! –

+4

.trigger मेरे लिए उपलब्ध नहीं था। मैंने .val ("जो भी") का उपयोग किया। इसके बजाय ट्रिगर हैडलर ("इनपुट") –

1

छोटा जवाब: बस तत्व पर change या input ट्रिगर मेरे लिए काम किया।

मूल रूप से

:

element.val('test').trigger('change') 
$rootScope.$digest() 

पार्सर आपके द्वारा जोड़े को गति प्रदान करना चाहिए।

0
element.trigger('input'); 

जब क्रोम में परीक्षण चल रहा है, लेकिन IE में इसे चलाने में विफल रहा है मेरे लिए काम किया।

element.trigger('change'); 

आईई और क्रोम दोनों में काम किया।

यही कारण है कि लोग विभिन्न परिणामों की रिपोर्ट कर रहे हैं।

संबंधित मुद्दे