2013-10-15 6 views
5

मैं AngularJS के v1.2.0 आरसी 2 का उपयोग कर रहा हूं और जानना चाहता हूं कि एकाधिक नियंत्रकों को सामान्य कार्यक्षमता प्रदान करने का सबसे अच्छा तरीका क्या है।

मैं निम्नलिखित सत्यापन कार्यों कि मैं सभी नियंत्रकों में उपयोग करना चाहते हैं कि एक मॉडल को संपादित किया है:

$scope.canSave = function (formController) { 
    return formController.$dirty && formController.$valid; 
}; 

$scope.validationClasses = function (modelController) { 
    return { 
     'has-error': modelController.$invalid && modelController.$dirty, 
     'has-success': modelController.$valid && modelController.$dirty 
    }; 
}; 

मैं अपने नियंत्रकों रखना चाहते हैं सूखी तो मैं एक कारखाने में परिभाषित किया गया इस प्रकार है:

angular.module('myModule', []) 
    .factory('validationFactory', [function() { 
     return { 
      validationClasses: function (modelController) { 
       return { 
        'has-error': modelController.$invalid && modelController.$dirty, 
        'has-success': modelController.$valid && modelController.$dirty 
       }; 
      }, 
      isFormValid: function (formController) { 
       return formController.$dirty && formController.$valid; 
      } 
     }; 
    }]); 

प्रारंभ में, मैं सिर्फ कारखाने नियंत्रकों है कि यह जरूरत में इस प्रकार मिलाया:

$scope.canSave = validationFactory.isFormValid; 

$scope.validationClasses = validationFactory.validationClasses; 

लेकिन मैं मैं के रूप में इस मॉड्यूल के रन विधि में $ rootScope करने के लिए उन्हें जोड़ सकता है एहसास हुआ:

angular.module('myModule', []) 
    .run([ 
     '$rootScope', 
     'validationFactory', 
     function ($rootScope, validationFactory) { 
      $rootScope.canSave = $rootScope.canUpdate = validationFactory.isFormValid; 
      $rootScope.validationClasses = validationFactory.validationClasses; 
     }]); 

अब वे अंधाधुंध हर नियंत्रक में उपलब्ध हैं और वहाँ कम तारों करने के लिए निर्भर है।

<form name="questionForm" novalidate> 
    <div class="form-group" ng-class="validationClasses(questionForm.question)"> 
     <label for="questionText" class="control-label">Text</label> 
     <input type="text" ng-model="question.text" name="question" 
       id="questionText" class="form-control" required/> 
     <span ng-show="questionForm.question.$error.required" 
       class="help-block">Question text is required</span> 
    </div> 
    ... 
    <div class="form-group" ng-switch on="action"> 
     <button type="button" ng-switch-when="New" ng-click="save()" 
       ng-disabled="!canSave(questionForm)" 
       class="btn btn-primary">Save</button> 
     <button type="button" ng-switch-default ng-click="update()" 
       ng-disabled="!canUpdate(questionForm)" 
       class="btn btn-primary">Update</button> 
     <button type="button" ng-click="cancel()" 
       class="btn btn-default">Cancel</button> 
    </div> 
</form> 

मेरे सवाल कर रहे हैं:

  1. मैं $ rootScope के लिए आम कार्यों जोड़ने से बचना चाहिए इस प्रकार

    कार्यों दृश्य टेम्पलेट्स में इस्तेमाल कर रहे हैं? यदि हां, तो क्या नुकसान है?

  2. क्या आवश्यक हो केवल सामान्य कार्यक्षमता में मिश्रण करना बेहतर है?
  3. क्या एक ही परिणाम प्राप्त करने का एक बेहतर तरीका है?

अपडेट किया गया समाधान

मैं $ rootScope जो इसके बारे में एक बुरा गंध था कार्यों जोड़ने के बजाय कस्टम निर्देशों का उपयोग करने का विकल्प चुना।

<div class="form-group" validation-class-for="question"> 
    <label for="questionText" class="control-label">Text</label> 
    <input type="text" ng-model="question.text" name="question" 
      id="questionText" class="form-control" required/> 
    <span ng-show="questionForm.question.$error.required" 
      class="help-block">Question text is required</span> 
</div> 

<button type="button" ng-click="save()" disabled-when-invalid 
    class="btn btn-primary">Save</button> 

निर्देशों बस एक रूप पूर्वज की आवश्यकता होती है और स्थिति का निर्धारण करने के लिए एक समारोह देखने के लिए:

मैं कस्टम validation-class-for="<input.name>" विशेषताओं और disabled-when-invalid तो मार्कअप इस तरह दिखता है बनाया।

angular.module('myModule', []) 
    .directive('validationClassFor', function() { 
     return { 
      require: '^form', 
      link: function (scope, element, attributes, formController) { 
       scope.$watch(function() { 
        var field = formController[attributes.validationClassFor]; 
        if (field.$invalid && field.$dirty) { 
         element.removeClass('has-success').addClass('has-error'); 
        } else if (field.$valid && field.$dirty) { 
         element.removeClass('has-error').addClass('has-success'); 
        } else { 
         element.removeClass('has-error').removeClass('has-success'); 
        } 
       }); 
      } 
     }; 
    }) 
    .directive('disabledWhenInvalid', function() { 
     return { 
      require: '^form', 
      link: function (scope, element, attributes, formController) { 
       scope.$watch(function() { 
        return formController.$dirty && formController.$valid; 
       }, function (value) { 
        element.prop('disabled', !value); 
       }); 
      } 
     }; 
    }); 

अब सत्यापन कारखाने की कोई आवश्यकता नहीं है।

उत्तर

1

आप इस सत्यापन का उपयोग कैसे कर रहे हैं फैक्ट्री? क्या सबमिट बटन के लिए इसे बदलना है? यदि ऐसा है, तो मैं बटन के लिए कस्टम घटक बनाने का सुझाव दूंगा, और घटक सत्यापन प्रमाणीकरण संदर्भित करेगा।

+0

मैं यह नियंत्रित करने के लिए फ़ंक्शंस का उपयोग कर रहा हूं कि सहेजें/अपडेट बटन अक्षम है और सीएसएस वर्ग जो फॉर्म समूह पर लागू होते हैं। – gwhn

2

मैं तर्क साझा करने के दायरे का उपयोग करने का सुझाव नहीं दूंगा। इससे पुन: प्रयोज्यता कम हो जाती है और जब आप इसका परीक्षण करना चाहते हैं तो इसका प्रभाव पड़ता है।

  • मैं निम्नलिखित तरीकों में से एक सुझाव है: आम तर्क को निकालने के लिए http://ejohn.org/blog/simple-javascript-inheritance/: आप वर्ग एक्सटेंशन का उपयोग कर सकते हैं।
  • आप घटनाओं को प्रसारित करने के लिए कोणीय के संदेश का उपयोग कर सकते हैं जो राज्य को टॉगल करता है, जैसे सत्यापनकर्ता से 'मान्य' है।
  • आप कुछ स्थितियों के आधार पर बैकएंड अनुरोधों को रोकने के लिए एक इंटरसेप्टर का उपयोग कर सकते हैं।
+0

मुझे लगता है कि आप टेस्टेबिलिटी पर असर के बारे में एक अच्छा मुद्दा बनाते हैं। टीबीएच मैंने सवाल पूछा क्योंकि मैंने सोचा था कि यह एक कोड गंध था। – gwhn

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