2014-07-21 13 views
5

सामान्य रूप से मेरे कोणीय/टाइपस्क्रिप्ट ऐप्स में मैंने "नियंत्रक के रूप में" वाक्यविन्यास का उपयोग करने का प्रयास किया है।

हालांकि, एक सीआरयूडी स्क्रीन के लिए मैं वर्तमान में काम कर रहा हूं, मैंने खुद को इस से दूर हटाना पाया है। ताकि मैं $watchCollection/परिवर्तनों की जांच आदि का लाभ उठा सकूं। मैंने अपने उत्कृष्ट चैप @ बसरत here द्वारा सुझाए गए पैटर्न का उपयोग करके खुद को पाया है। अर्थात्, वीडियो में (जो पूर्व-दिनांक "एंगुलर में" नियंत्रक के रूप में "नियंत्रक है) @basarat $scope पर vm नामक नियंत्रक का प्रतिनिधित्व करने वाला एक चर बनाता है। और उसी तरह से दृश्य में "नियंत्रक के रूप में नियंत्रक" का उपयोग करने के साथ ही आप अपने मॉडल के साथ संवाद करने के लिए vm.myProperty/vm.myFunction() शैली वाक्यविन्यास का उपयोग कर सकते हैं।

तो, नियंत्रक इस तरह दिखता है:

module controllers { 

    "use strict"; 

    interface sageEditRouteParams extends ng.route.IRouteParamsService { 
     id: number; 
    } 

    interface sageEditScope extends ng.IScope { 
     vm: SageEdit; 
    } 

    class SageEdit { 

     log: loggerFunction; 
     sage: sage; 
     title: string; 

     private _hasChanges: boolean; 

     static $inject = ["$routeParams", "$scope", "common", "datacontext"]; 
     constructor(
      private $routeParams: sageEditRouteParams, 
      private $scope: sageEditScope, 
      private common: common, 
      private datacontext: datacontext 
      ) { 

      this.sage = undefined; 
      this.title = "Sage Edit"; 

      this.log = common.logger.getLogFn(controllerId); 

      $scope.vm = this; 
      $scope.$watchCollection("vm.sage", (newSage: sage, oldSage: sage) => { 
       if (newSage && oldSage) { 
        this._hasChanges = true; 
       } 
      }); 

      this.activate(); 
     } 

     // Prototype methods 

     activate() { 
      var id = this.$routeParams.id; 
      var dataPromises: ng.IPromise<any>[] = [this.getSage(id)]; 

      this.common.activateController(dataPromises, controllerId) 
       .then(() => { 
        this.log("Activated Sage Edit View"); 
        this.title = "Sage Edit: " + this.sage.name; 
       }); 
     } 

     getSage(id: number) { 
      return this.datacontext.sage.getById(id).then(data => { 
       this.sage = data; 
       this._hasChanges = false; 
      }); 
     } 

     get hasChanges(): boolean { 
      return this._hasChanges; 
     } 
    } 

    var controllerId = "sageEdit"; 
    angular.module("app").controller(controllerId, SageEdit); 
} 

और इस तरह दृश्य:

<section class="mainbar" ng-controller="sageEdit"> 
    <section class="matter"> 
     <div class="container-fluid"> 
      <div> 
       <button class="btn btn-info" 
         ng-click="vm.cancel()" 
         ng-disabled="!vm.canSave"> 
        <i class="fa fa-undo"></i>Cancel 
       </button> 
       <button class="btn btn-info" 
         ng-click="vm.save()" 
         ng-disabled="!vm.canSave"> 
        <i class="glyphicon glyphicon-save"></i>Save 
       </button> 
       <span ng-show="vm.hasChanges" 
         class="dissolve-animation ng-hide"> 
        <i class="glyphicon glyphicon-asterisk text-info"></i> 
       </span> 
      </div> 
      <div class="widget wgreen"> 
       <div data-cc-widget-header title="{{vm.title}}"></div> 
       <div class="widget-content form-horizontal"> 
        <div class="form-group"> 
         <label class="col-xs-12 col-sm-2">Name</label> 
         <input class="col-xs-12 col-sm-9" ng-model="vm.sage.name" /> 
        </div> 
        <div class="form-group"> 
         <label class="col-xs-12 col-sm-2">Username</label> 
         <input class="col-xs-12 col-sm-9" ng-model="vm.sage.userName" /> 
        </div> 
        <div class="form-group"> 
         <label class="col-xs-12 col-sm-2">Email</label> 
         <input class="col-xs-12 col-sm-9" 
           type="email" 
           ng-model="vm.sage.email" /> 
        </div> 
       </div> 
      </div> 
     </div> 
    </section> 
</section> 

क्या मैं एक साथ डाल रहा हूं ठीक काम करने के लिए लगता है, लेकिन मैं इसे बाहर रखना चाहते थे वहां और कुछ अन्य विचार प्राप्त करें। देखते हैं:

  1. इस दृष्टिकोण
  2. कोई कारण यह एक बुरा विचार है
  3. बेहतर विकल्प के साथ किसी भी कमियों?

मैंने थोड़ा खुदाई की है लेकिन कुछ भी निर्णायक नहीं मिला है।

+1

उल्लेख के लिए 'नियंत्रक के रूप में धन्यवाद' के जवाब का उत्तर भी अपडेट किया गया है; – basarat

उत्तर

6

जादू स्ट्रिंग हटाने

लिए

$scope.$watchCollection("vm.sage", (newSage: sage, oldSage: sage) => { 

तुम भी रिफैक्टरिंग आसानी के लिए कर सकते हैं:

$scope.$watchCollection(()=>this.sage, (newSage: sage, oldSage: sage) => { 

कुछ स्थितियों में जहां foo अभी भी अपरिभाषित है जब आप foo.bar की तरह कुछ देखने के लिए कोशिश आप एक सुरक्षित रैपर फ़ंक्शन का उपयोग कर सकते हैं safeWatch(()=>this.foo.bar):

function safeWatch<T extends Function>(expression: T) { 
     return() => { 
      try { 
       return expression(); 
      } 
      catch (e) { 
       return null; 
      } 
     }; 
    } 

नियंत्रक बनाम के रूप में $ scope.vm

Fron स्रोत कोड: https://github.com/angular/angular.js/blob/36831eccd1da37c089f2141a2c073a6db69f3e1d/src/ng/controller.js#L95

है यही आप के लिए क्या कोणीय कर रही है। यानी $scope.vm = instance (जहां vm == indentifier) तो वे समकक्ष

+1

धन्यवाद @ बसरत - एक इलाज करता है! (मेरे अंदर ओसीडी प्रोग्रामर "** ** होना चाहिए ** लगातार कोड होना चाहिए" संतुष्ट है) –

+0

एकमात्र मुद्दा तब होता है जब आप 'foo' अभी तक परिभाषित नहीं होने पर' this.foo.bar' जैसे कुछ देखते हैं। इसके लिए हमारे पास 'सुरक्षित मूल्यांकन' कार्य है। मुझे इसे भी पोस्ट करने दें। – basarat

+0

'' 'safeWatch''' के लिए अच्छा है - धन्यवाद चैप! –

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