একটি কৌণিক জেএস নিয়ামক একই মডিউলে অন্য নিয়ামকের কাছ থেকে উত্তরাধিকারী হতে পারে?


198

একটি মডিউল মধ্যে, একটি নিয়ামক বাইরের নিয়ামক দ্বারা সম্পত্তি উত্তরাধিকারী হতে পারে:

var app = angular.module('angularjs-starter', []);

var ParentCtrl = function ($scope, $location) {
};

app.controller('ChildCtrl', function($scope, $injector) {
  $injector.invoke(ParentCtrl, this, {$scope: $scope});
});

এর মাধ্যমে উদাহরণ: মৃত লিঙ্ক : http://blog.omkarpatil.com/2013/02/controller-inheritance-in-angularjs.html

মডিউলটির অভ্যন্তরেও কোনও নিয়ামক কি কোনও ভাইবোন থেকে উত্তরাধিকারী হতে পারেন?

var app = angular.module('angularjs-starter', []);

app.controller('ParentCtrl ', function($scope) {
  //I'm the sibling, but want to act as parent
});

app.controller('ChildCtrl', function($scope, $injector) {
  $injector.invoke(ParentCtrl, this, {$scope: $scope}); //This does not work
});

দ্বিতীয় $injector.invokeকোডটিতে কাজ করা হয় না যেহেতু প্রথম প্যারামিটার হিসাবে কোনও ফাংশন প্রয়োজন এবং এর রেফারেন্সটি খুঁজে পায় না ParentCtrl



2
একদিকে: এটি উত্তরাধিকারের মতো দেখায় না, তবে ভাগ করে নেওয়ার পদ্ধতি বা ইনজেকশনের মতো more সম্ভবত কেবল শব্দার্থক।
alockwood05

উদাহরণের লিঙ্কটি আর বৈধ নয়।
অ্যালেক্সএস

গুগল ক্যাশে লিংক: webcache.googleusercontent.com/… যা এই আকর্ষণীয় ফিডলকে নির্দেশ করে: jsfiddle.net/mhevery/u6s88/12
ফেডেরিকো

উত্তর:


289

হ্যাঁ, তবে এটির $controllerপরিবর্তে আপনাকে নিয়ন্ত্রকটি ইনস্ট্যান্ট করতে পরিষেবাটি ব্যবহার করতে হবে: -

var app = angular.module('angularjs-starter', []);

app.controller('ParentCtrl', function($scope) {
  // I'm the sibling, but want to act as parent
});

app.controller('ChildCtrl', function($scope, $controller) {
  $controller('ParentCtrl', {$scope: $scope}); //This works
});

ParentCtrlএটি একটি controllerবা এটি ব্যবহার করা সম্ভব service?
গন্টার্ড

@ গন্টার্ড: এক্ষেত্রে এটি অবশ্যই একটি নিয়ামক হতে হবে, কারণ $controllerএটি কেবল নিবন্ধীকৃত নিয়ামক ব্যবহার করতে পারে।
জিসিস

10
এটি একটি খুব ভাল সমাধান। ধন্যবাদ. তবে আমি কন্ট্রোলার হিসাবে সিনট্যাক্স হিসাবে ব্যবহার করছি সে ক্ষেত্রে এটি কীভাবে করব?
কা

1
উপরোক্ত প্রশ্নটি প্রশ্ন হিসাবে জিজ্ঞাসা করা হয়েছিল। এটি লক্ষণীয় যে কন্ট্রোলাররা কেবল কন্ট্রোলারটিকে স্কোপের জন্য নির্ধারিত করে - সুতরাং আপনি (তত্ত্ব অনুসারে) পরিবর্তন $scopeকরবেনthis
ড্যান প্যান্ট্রি

4
এটি আমার পক্ষে কাজ করেছে, তবে আমি একই পাতায় পিতা বা মাতা নিয়ামক এবং শিশু নিয়ামক রাখার উপায়ে এটি করার চেষ্টা করছি। এর ফলে প্যারেন্ট কন্ট্রোলারে $ http অপারেশন দু'বার চালিত হয়। যখন বাচ্চা নিয়ামক পিতামাতার নিয়ন্ত্রকের স্কোপটিকে আমার $ সুযোগটি ইনজেক্ট করে। সমস্ত মেম্বার অ্যারে প্যারেন্ট কন্ট্রোলারটির চালনার কারণ হিসাবে এটি দ্বিগুণ হয়ে যায়, তখন শিশু নিয়ামক এটি আবার চালনার কারণ হয়। তা রোধ করার কোনও উপায় আছে কি?
রায়ান মান 20

20

আপনি যদি vmনিয়ামক বাক্য গঠন ব্যবহার করেন তবে আমার সমাধানটি এখানে:

.controller("BaseGenericCtrl", function ($scope) {

    var vm = this;
    vm.reload = reload;
    vm.items = [];

    function reload() {
        // this function will come from child controller scope - RESTDataService.getItemsA
        this.getItems();
    }
})

.controller("ChildCtrl", function ($scope, $controller, RESTDataService) {
    var vm = this;
    vm.getItems = RESTDataService.getItemsA;
    angular.extend(vm, $controller('BaseGenericCtrl', {$scope: $scope}));
})

দুর্ভাগ্যক্রমে, আপনি ব্যবহার করতে পারবেন না $controller.call(vm, 'BaseGenericCtrl'...), বর্তমান প্রসঙ্গটি বন্ধকরণের জন্য ( reload()ফাংশন) রূপান্তর করতে, সুতরাং thisপ্রসঙ্গটিকে পরিবর্তনশীল করার জন্য উত্তরাধিকার সূত্রে ফাংশনটির অভ্যন্তরীণ কেবলমাত্র একটি সমাধান ব্যবহার করা উচিত ।


আপনি কি কেবল এর পরিবর্তে এটি করতে পারতেন না? > $ নিয়ামক ('বেসজেনারিক নিয়ন্ত্রণ), {ভিএম: ভিএম});
হারিংটাউন

vmনিয়ামকের অভ্যন্তরে কেবল একটি পরিবর্তনশীল, আমার মনে হয় না যে কৌণিকটি এটি প্রত্যাশার মতো ব্যবহার করতে পারে।
আইপ্রোব্লেমফ্যাক্টরি

8

আমি মনে করি, উভয় নিয়ামকের জন্য অ্যাক্সেসযোগ্য ফাংশন বা ডেটা দেওয়ার জন্য আপনার কারখানা বা পরিষেবা ব্যবহার করা উচিত।

এখানে অনুরূপ প্রশ্ন ---> AngularJS নিয়ামক উত্তরাধিকার


হ্যাঁ এটি একটি উপায়, ধন্যবাদ। আমি সমাধানটি অনুসন্ধান করার সময় আমি সেই পোস্টটি জুড়ে এসেছি। আমি ভাবছিলাম যদি কন্ট্রোলার ফাংশনটি লোড করার এবং এর সাথে "এটি" প্রসারিত করার কোনও উপায় থাকে তবে।
কা

আমি সর্বজনীন loadingপরিবর্তনশীল রাখতে চাই যাতে ডেটা লোড হওয়ার সময় আমি সর্বদা একই জিনিস করি, আমি মনে করি না কারখানাগুলি এটি করতে পারে। আমার প্যারেন্ট কন্ট্রোলারের একটি লোডিং ভেরিয়েবল থাকতে পারে তবে কারখানাটি এটি পরিচালনা করতে পারে না ... ঠিক ?!
পিক্সম্যাচ

7

জিএমটিগের এই উত্তরে উত্থাপিত সমস্যার জবাবে আমি $ কন্ট্রোলার () ব্যবহার করে একটি নিয়ামককে উত্তরাধিকারী করার জন্য একটি পদ্ধতি পেয়েছি এবং এখনও নিয়ামকটিকে "সিনট্যাক্স হিসাবে" ব্যবহার করি।

প্রথমত, আপনি যখন কলিং inherit নিয়ামক () এর উত্তরাধিকারী হন তখন "হিসাবে" সিনট্যাক্স ব্যবহার করুন:

    app.controller('ParentCtrl', function(etc...) {
        this.foo = 'bar';
    });
    app.controller('ChildCtrl', function($scope, $controller, etc...) {
        var ctrl = $controller('ParentCtrl as parent', {etc: etc, ...});
        angular.extend(this, ctrl);

    });

তারপরে, এইচটিএমএল টেমপ্লেটে, সম্পত্তিটি পিতামাতার দ্বারা সংজ্ঞায়িত করা হয়, তবে parent.পিতা-মাতার কাছ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত সম্পত্তি পুনরুদ্ধার করতে ব্যবহার করুন ; যদি সন্তানের দ্বারা সংজ্ঞায়িত করা হয়, তবে child.এটি পুনরুদ্ধার করতে ব্যবহার করুন ।

    <div ng-controller="ChildCtrl as child">{{ parent.foo }}</div>

5

ঠিক আছে, আমি এটি অন্য উপায়ে করেছি। আমার ক্ষেত্রে আমি এমন একটি ফাংশন চেয়েছিলাম যা অন্যান্য নিয়ামকগুলিতে একই ফাংশন এবং বৈশিষ্ট্যগুলি প্রয়োগ করে। পরামিতি বাদে আমি এটি পছন্দ করেছি। এইভাবে, আপনার সমস্ত চাইল্ডক্রিটের receive অবস্থান নেওয়া দরকার।

var app = angular.module('angularjs-starter', []);

function BaseCtrl ($scope, $location) {
    $scope.myProp = 'Foo';
    $scope.myMethod = function bar(){ /* do magic */ };
}

app.controller('ChildCtrl', function($scope, $location) {
    BaseCtrl.call(this, $scope, $location);

    // it works
    $scope.myMethod();
});

4

যারা ভাবছেন তাদের জন্য, আপনি গ্রহণযোগ্য উত্তরে পদ্ধতিটি ব্যবহার করে একই ফ্যাশনে উপাদান নিয়ন্ত্রকগুলি প্রসারিত করতে পারেন।

নিম্নলিখিত পদ্ধতির ব্যবহার করুন:

মূল উপাদান (থেকে প্রসারিত):

/**
 * Module definition and dependencies
 */
angular.module('App.Parent', [])

/**
 * Component
 */
.component('parent', {
  templateUrl: 'parent.html',
  controller: 'ParentCtrl',
})

/**
 * Controller
 */
.controller('ParentCtrl', function($parentDep) {

  //Get controller
  const $ctrl = this;

  /**
   * On init
   */
  this.$onInit = function() {

    //Do stuff
    this.something = true;
  };
});

শিশু উপাদান (এক প্রসারিত):

/**
 * Module definition and dependencies
 */
angular.module('App.Child', [])

/**
 * Component
 */
.component('child', {
  templateUrl: 'child.html',
  controller: 'ChildCtrl',
})

/**
 * Controller
 */
.controller('ChildCtrl', function($controller) {

  //Get controllers
  const $ctrl = this;
  const $base = $controller('ParentCtrl', {});
  //NOTE: no need to pass $parentDep in here, it is resolved automatically
  //if it's a global service/dependency

  //Extend
  angular.extend($ctrl, $base);

  /**
   * On init
   */
  this.$onInit = function() {

    //Call parent init
    $base.$onInit.call(this);

    //Do other stuff
    this.somethingElse = true;
  };
});

কৌশলটি হ'ল নামকরণকারী কন্ট্রোলারগুলি উপাদানগুলির সংজ্ঞাতে সংজ্ঞায়নের পরিবর্তে ব্যবহার করা।


2

গৃহীত উত্তরে উল্লিখিত হিসাবে, আপনি $controller('ParentCtrl', {$scope: $scope, etc: etc});আপনার সন্তানের নিয়ামককে কল করে পিতা বা মাতা নিয়ন্ত্রকের $ স্কোপ এবং অন্যান্য পরিষেবায় পরিবর্তনগুলি "উত্তরাধিকারী" করতে পারেন:

তবে , যদি আপনি নিয়ামককে 'হিসাবে' সিনট্যাক্স ব্যবহার করতে অভ্যস্ত হন, তবে এটি ব্যর্থ হয় in

<div ng-controller="ChildCtrl as child">{{ child.foo }}</div>

যদি fooপ্যারেন্ট কন্ট্রোলারে (মাধ্যমে this.foo = ...) সেট করা থাকে তবে শিশু নিয়ামকের এতে অ্যাক্সেস থাকবে না।

মন্তব্যে উল্লিখিত হিসাবে আপনি সরাসরি স্কোপগুলিতে নিয়ামকের ফলাফল নির্ধারণ করতে পারেন:

var app = angular.module('angularjs-starter', []);
app.controller('ParentCtrl ', function(etc...) {
    this.foo = 'bar';
});
app.controller('ChildCtrl', function($scope, $controller, etc...) {
    var inst = $controller('ParentCtrl', {etc: etc, ...});

    // Perform extensions to inst
    inst.baz = inst.foo + " extended";

    // Attach to the scope
    $scope.child = inst;
});

দ্রষ্টব্য: তারপরে আপনাকে অবশ্যই 'হিসাবে' অংশটি সরিয়ে ফেলতে হবেng-controller= , কারণ আপনি কোডে উদাহরণের নামটি নির্দিষ্ট করছেন, এবং আর টেমপ্লেট নেই no


"নিয়ামক হিসাবে" সিনট্যাক্স ব্যবহার করার কোনও সমস্যা নেই। আমার উত্তর দেখার stackoverflow.com/a/36549465/2197555
gm2008

2

আমি "নিয়ামক হিসাবে" সিনট্যাক্সটি ব্যবহার করে vm = thisএকটি নিয়ামকের উত্তরাধিকারী হতে চাইছিলাম। আমার প্যারেন্ট কন্ট্রোলারের একটি ফাংশন ছিল যা ভেরিয়েবল পরিবর্তন করে।

ব্যবহার IProblemFactory এর এবং সালমান আব্বাসের উত্তর, আমি পিতা বা মাতা ভেরিয়েবল এক্সেস আছে নিম্নলিখিত যা করেছে:

(function () {
  'use strict';
  angular
      .module('MyApp',[])
      .controller('AbstractController', AbstractController)
      .controller('ChildController', ChildController);

  function AbstractController(child) {
    var vm = child;
    vm.foo = 0;
    
    vm.addToFoo = function() {
      vm.foo+=1;
    }
  };
  
  function ChildController($controller) {
    var vm = this;
    angular.extend(vm, $controller('AbstractController', {child: vm}));
  };
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="ChildController as childCtrl" layout="column" ng-cloak="" ng-app="MyApp">
  <button type="button" ng-click="childCtrl.addToFoo()">
    add
  </button>
  <span>
      -- {{childCtrl.foo}} --
  </span>
</div>


0

আপনি একটি সাধারণ জাভাস্ক্রিপ্ট উত্তরাধিকার প্রক্রিয়া ব্যবহার করতে পারেন। .Call পদ্ধতিটি শুরু করার জন্য একটি প্রয়োজনীয় কৌণিক পরিষেবাগুলি পাস করতে ভুলবেন না।

//simple function (js class)
function baseCtrl($http, $scope, $location, $rootScope, $routeParams, $log, $timeout, $window, modalService) {//any serrvices and your 2

   this.id = $routeParams.id;
   $scope.id = this.id;

   this.someFunc = function(){
      $http.get("url?id="+this.id)
      .then(success function(response){
        ....
       } ) 

   }
...
}

angular
        .module('app')
        .controller('childCtrl', childCtrl);

//angular controller function
function childCtrl($http, $scope, $location, $rootScope, $routeParams, $log, $timeout, $window, modalService) {      
   var ctrl = this;
   baseCtrl.call(this, $http, $scope, $location, $rootScope,  $routeParams, $log, $timeout, $window, modalService);

   var idCopy = ctrl.id;
   if($scope.id == ctrl.id){//just for sample
      ctrl.someFunc();
   }
}

//also you can copy prototype of the base controller
childCtrl.prototype = Object.create(baseCtrl.prototype);

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.